Assembly Language for Beginners

(nextflipdebug2) #1
3.29. WINDOWS 16-BIT
loc_86: ; CODE XREF: remove_digits+Aj
pop bp
retn 2
remove_digits endp

WinMain proc near ; CODE XREF: start+EDp
push bp
mov bp, sp
mov ax, offset aAsd ; "asd"
push ax
mov ax, offset aDef ; "def"
push ax
call string_compare
push ds
mov ax, offset aAsd ; "asd"
push ax
push ds
mov ax, offset aDef ; "def"
push ax
call string_compare_far
mov ax, offset aHello1234World ; "hello 1234 world"
push ax
call remove_digits
xor ax, ax
push ax
push ds
mov ax, offset aHello1234World ; "hello 1234 world"
push ax
push ds
mov ax, offset aCaption ; "caption"
push ax
mov ax, 3 ; MB_YESNOCANCEL
push ax
call MESSAGEBOX
xor ax, ax
pop bp
retn 0Ah
WinMain endp

Here we see a difference between the so-called “near” pointers and the “far” pointers: another weird
artifact of segmented memory in 16-bit 8086.

You can read more about it here:11.6 on page 1003.

“near” pointers are those which point within the current data segment. Hence, thestring_compare()
function takes only two 16-bit pointers, and accesses the data from the segment thatDSpoints to (The
mov al, [bx]instruction actually works likemov al, ds:[bx]—DSis implicit here).


“far” pointers are those which may point to data in another memory segment.
Hencestring_compare_far()takesthe16-bitpairasapointer,loadsthehighpartofitintheESsegment
register and accesses the data through it
(mov al, es:[bx]). “far” pointers are also used in my
MessageBox()win16 example:3.29.2 on page 650. Indeed, the Windows kernel is not aware which data
segment to use when accessing text strings, so it need the complete information.


The reason for this distinction is that a compact program may use just one 64kb data segment, so it
doesn’t need to pass the high part of the address, which is always the same. A bigger program may use
several 64kb data segments, so it needs to specify the segment of the data each time.

It’s the same story for code segments. A compact program may have all executable code within one
64kb-segment, then all functions in it will be called using theCALL NEARinstruction, and the code flow
will be returned usingRETN. But if there are several code segments, then the address of the function is to
be specified by a pair, it is to be called using theCALL FARinstruction, and the code flow is to be returned
usingRETF.

This is what is set in the compiler by specifying “memory model”.

The compilers targeting MS-DOS and Win16 have specific libraries for each memory model: they differ by
pointer types for code and data.
Free download pdf