Microsoft KB Archive/41531
Article ID: 41531
Article Last Modified on 8/16/2005
- Microsoft Visual Basic for MS-DOS
- Microsoft QuickBasic 4.0
- Microsoft QuickBASIC 4.0b
- Microsoft QuickBasic 4.5 for MS-DOS
This article was previously published under Q41531
The DEF SEG statement in Basic sets the current segment address for a subsequent PEEK function, or a subsequent POKE, BLOAD, BSAVE, or CALL ABSOLUTE statement. PEEK, POKE, BLOAD, BSAVE, and CALL ABSOLUTE can all specify an offset (from the current segment) as an argument.
You can calculate the absolute address (the n'th byte) in memory from the segment and offset as follows:
- Multiply the segment address by 16 (or shift the hexadecimal representation 1 to the left, adding zero to the right-most digit; for example, &H40 times 16 equals &H400).
- Add this value to the offset.
In the 8086 chip architecture, the addressable memory space is divided into segments, each of which can contain up to 64K of memory. Segments can only start on a paragraph address. A paragraph address is a byte location that is evenly divisible by 16 bytes. Every 16th byte in memory contains segment number n. To access specific bytes or words in memory, you must use an offset relative to the beginning of a specified segment.
Together, a segment and an offset provide a segmented address that can locate any byte in the 1 megabyte of address space in the 8086 processor.
The following PEEK function returns 1 byte located at an offset from the paragraph address of the current segment:
' To try this example in VBDOS.EXE: ' 1. From the File menu, choose New Project. ' 2. Copy the code example to the Code window. ' 3. Press F5 to run the program. DEF SEG=paddress ' Sets paragraph address of "current" segment. x% = PEEK(offset) ' A byte is returned in integer variable x%.
The following book contains more information about 8086-segmented architecture and memory addressing:
"The New Peter Norton Programmer's Guide to the IBM PC & PS/2," by Peter Norton and Richard Wilton (published by Microsoft Press, 1988).
The following two PEEK functions access the same location in memory starting from two different segments (using decimal notation):
' To try the following examples in VBDOS.EXE: ' 1. From the File menu, choose New Project. ' 2. Copy the code example to the Code window. ' 3. Press F5 to run the program. DEF SEG = 0 x% = PEEK(256) ' PEEKs at address 0000:0256 decimal. print x% DEF SEG = 1 ' The next segment is 16 bytes higher. y% = PEEK(240) ' PEEKs at address 0001:0240 decimal. print y%
The previous lines of code print the same PEEKed value because (0 * 16) + 256 equals (1 * 16) + 240.
The following is another example of two PEEK functions accessing the same location in memory starting from two different segments, this time using hexadecimal notation:
' To try the following examples in VBDOS.EXE: ' 1. From the File menu, choose New Project. ' 2. Copy the code example to the Code window. ' 3. Press F5 to run the program. DEF SEG = 0 x% = PEEK(&H417) ' PEEKs at address 0000:0417 Hexadecimal. print x% DEF SEG = &H40 y% = PEEK(&H17) ' PEEKs at address 0040:0017 Hexadecimal. print x%
The previous lines of code access the same values and print them because they have the same absolute address: (0h + 417h) equals (400h + 17h).
Remember, when you calculate the absolute address, you shift the segment address 1 digit to the left in hexadecimal notation (i.e., multiply by 16 decimal, or 10h) and then add to the offset: 40h times 10h equals 400h, which is added to 17h.
Additional query words: VBmsdos QuickBas 1.00 4.00 4.00b 4.50