Use of the 32-bit register set of the 386 and above processor will be
examined along with minor changes to the way that we have been
writing Assembler programs. Use of the Visual C++ environment for debugging
32-bit Assembler programs will also be examined in
the following.
010 Carry 0 1 0 Carry 627 +6 +2 +7 +246 +2 +4 +6 873 8 7 3 |
011 Borrow 0 1 1 Borrow 647 6 4 7 -478 -4 -7 -8 169 1 6 9 |
| Adc Al, Bh | Sbb Al, Bh |
Al +CF +Bh Al |
Al -CF -Bh Al |
Examples of adding 12341234567856789ABC9ABCx + CBA9CBA98765876543214321x
and subtracting CBA9CBA98765876543214321x - 12341234567856789ABC9ABCx are
below. In both cases the result is in the combined three registers eAx:eBx:eCx.
Mov eAx, 12341234h Mov eBx, 56785678h Mov eCx, 9ABC9ABCh Mov eDx, 0CBA9CBA9h Mov eSi, 87658765h Mov eDi, 43214321h Add eCx, eDi Adc eBx, eSi Adc eAx, eDx |
Mov eAx, 12341234h Mov eBx, 56785678h Mov eCx, 9ABC9ABCh Mov eDx, 0CBA9CBA9h Mov eSi, 87658765h Mov eDi, 43214321h Sub eCx, eDi Sbb eBx, eSi Sbb eAx, eDx |
eAx:eBx:eCx +eDx:eSi:eDi eAx:eBx:eCx |
eAx:eBx:eCx -eDx:eSi:eDi eAx:eBx:eCx |
purposes of writing C callable assembler functions, we are only interested
in one aspect of the 386, the 32-bit register set. The key point is all
registers except the segment registers have 32-bit versions, the
segment registers are still 16-bit. The format of the X-registers and others
are illustrated at right. For example, the eAx register is 32-bit
with the low 16 bits being Ax. Ax is still 16-bit, Ah and Al are 8-bit.
eBp, eSp, eDi, and eSi are 32-bit versions with the16-bit version in the
low bits (i.e. Bp. Sp, Di, and Si). The segment registers still serve the
same purpose as before except now the segments are 232 rather
than 216 memory bytes.
Real and Protected Mode - Most 16-bit instructions are also 32-bit, addition, subtraction, move, etc. Multiplication of two 32-bit operands, one in eAx, produces a 64-bit result in eDx:eAx; division uses eDx:eAx for the dividend, eAx is the quotient and eDx the remainder.
Push and Pop instructions behave differently whether for real or 16-bit mode (a 16-bit value is pushed or popped) or protected or 32-bit mode (a 32-bit value is pushed or popped). For example:
eAx *eBx eDx:eAxeAx eBx / eDx:eAx eDx
16-bit Push Ax Pop Ax PushA PopA PushF PopF |
32-bit Push eAx Pop eAx PushAD PopAD PushFD PopFD |
32-bit programming requires some changes to programs and input/output routines. The following compares a 16-bit versus on the left with a 32-bit program on the right. The changes are given in bold. The following is an example of assembling the HelloWorld.asm program:
16-bit vs. 32-bit Assembler Hello World
Extrn PutStrng:Far
data Segment
HelloWorld db 'Hello World'
data Ends
code Segment
Main proc Near
Assume Cs:code, Ds:data
Mov Bx, Seg Data
Mov Ds, Bx
Mov Es, Bx
Lea Di, HelloWorld
Mov Cx, 11
Call PutStrng
Mov Ah, 4ch ;Stop
Int 21h
Main endp
code Ends
end Main
|
.386
.model flat, stdcall
include kernel32.inc
include masm32.inc
includelib kernel32.lib
includelib masm32.lib
WriteString proto
.data
HelloWorld db 'Hello World',0
.code
Main proc Near
Lea eDX, HelloWorld
Call WriteString
Main endp
end Main
|
A more complex example in C++ and Assembler to compute the maximum of two unsigned numbers.
// maximum.cpp
#include <iostream.h>
int X, Y;
char *IsMaximum = " is maximum\r\n";
char *PromptX = Enter X:\r\n";
char *PromptY = Enter Y:\r\n";
void main( void ) {
cout << PromptX;
cin >> X;
cout << PromptY;
cin >> Y;
if (X > Y)
cout << X;
else
cout << Y;
cout << IsMaximum;
}
|
; Maximum.Asm
.386
.model flat, stdcall
include kernel32.inc
include masm32.inc
includelib kernel32.lib
includelib masm32.lib
WriteString proto
ReadDec proto
WriteDec proto
.data
X dd ?
Y dd ?
IsMaximum db ' is maximum',0, 10, 13
PromptX db 'Enter X:',0, 10, 13
PromptY db 'Enter Y:',0, 10, 13
.code
Main proc Near
Lea eDX, PromptX
Call WriteString
Call ReadDec
Mov X, eAx
Lea eDX, PromptY
Call WriteString
Call ReadDec
Mov Y, eAx
ifA:
Mov eAx, X
Cmp eAx, Y
Jg thenA
Jmp elseA
thenA:
Mov eAx, X
Call WriteDec
Jmp endifA
elseA:
Mov eAx, Y
Call PutDec
endifA:
Lea eDx, IsMaximum
Call WriteString
Main endp
end Main
|
For now there are five basic input/output routines similar to those for 16-bit programs supplied by the text. See the above Maximum.asm program for a complete example. Note that these are case sensitive. The 32-bit routines are:
The
Visual Studio debugger can be used to debug 32-bit Assembler executable programs.
