Copyright © 2000, Daniel W. Lewis. All Rights Reserved. CHAPTER 5 MIXING C AND ASSEMBLY
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
CHAPTER 5
MIXING C AND ASSEMBLY
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
L1: MOV EAX,[RESULT+2] ; load selected table element
The Four Fields of a Line of Code in Assembly Language
Label FieldLabel Field
OperationField
OperationField
Operand Fields
Operand Fields
Comment Field
Comment Field
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Use of “[…]” in NASM Assembler
ORG 1234hxyzzy: DD 5678h ; the address of this word is 1234 (hex)
...MOV EAX,[xyzzy]; loads 5678 (hex) into
register EAX…MOV EAX,xyzzy ; loads 1234 (hex) into
register EAX
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Two Passes of an Assembler ...
...
...
A0
05 07
&x+21B27
3F3A
...
...
...
A0
05 07
1B27
3F3A
3F3C
...
MOV AL,[X+2]
...
X DB 5,7,3
...
Asse
mb
ler P
ass 1
Asse
mb
ler P
ass 1
Asse
mb
ler P
ass 2
Asse
mb
ler P
ass 2Symbol Table
3F3AX
… …
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Instruction Sequencing
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
for (;;) top_of_for: ...
{... ...if (...) break ; JMP end_of_for... ...} JMP top_of_for
end_of_for: ...
Code Generated by Compiler for Break and End of Loop
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Commonly-Used Conditional Jump Instructions
Compare
Mnemonic(s)
Jump if . . . Determined by . . .
equalityJE (JZ) Equal (Zero) ZF==1
JNE (JNZ) Not Equal (Not Zero) ZF==0
unsigned
JB (JNAE) Below (Not Above or Equal) CF==1
JBE (JNA) Below or Equal (Not Above) CF==1 || ZF==1
JAE (JNB) Above or Equal (Not Below) CF==0
JA (JNBE) Above (Not Below or Equal) CF==0 && ZF==0
signed
JL (JNGE)Less than (Not Greater than or Equal)
SF!=OF
JLE (JNG)Less than or Equal (Not Greater than)
SF!=OF || ZF==1
JGE (JNL)Greater than or Equal (Not Less than)
SF==OF
JG (JNLE)Greater than (Not Less than or Equal)
SF==OF && ZF==0
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Conditional Jump Preceded by a CMP Instruction
while (x < 1000) top_of_while: CMP DWORD [x],1000
{ JNL end_of_while... ...} JMP top_of_while
end_of_while:
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Compound Conditionals
if (lower_limit <= x && x <= upper_limit) y = x ;
if (x < lower_limit) goto L1if (x > upper_limit) goto L1y = x ;
L1:
if (x < lower_limit || x > upper_limit) goto L1y = x ;
L1:
if (!(lower_limit <= x && x <= upper_limit)) goto L1
y = x ;L1:
MOV EAX,[x]CMP EAX,
[lower_limit] JLL1CMP EAX,
[upper_limit] JGL1MOV [y],EAX
L1: ...
Convert “then” clause to a goto
Convert AND to OR so if can be split
Split into two if’s
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Compound Conditionalsif (x < lower_limit || upper_limit < x) y = x ;
if (x < lower_limit) goto L1 if (x > upper_limit) goto L1 goto L2 ;L1: y = x ;L2:
if (x < lower_limit) goto L1 if (!(x > upper_limit)) goto L2L1: y = x ;L2:
MOV EAX,[x]CMP EAX,
[lower_limit] JL L1CMP EAX,
[upper_limit] JNG L2
L1: MOV [y],EAXL2: ...
if (x < lower_limit || upper_limit < x) goto L1 ; goto L2 ;L1: y = x ;L2:
Convert “then” clause to a goto
Split into two if’s
Reverse the sense to eliminate extra goto
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
If-Then-Else Statements
if (x > y) MOV EAX,[x] ; x > y ?{ CMP EAX,[y]x = 0 ; JNG L1} MOV DWORD [x],0 ; then: x = 0 ;
else JMP L2 ; skip over else
{ L1: MOV DWORD [y],0 ; else: y = 0 ;y = 0 ; L2: ...}
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Building a Loop With the JECXZ and LOOP Instructions
MOV ECX,[iteration_count] JECXZ loop_exit ; jump if ECX is zero.
top_of_loop:...<Register ECX: N, N-1, ... 1>...LOOP top_of_loop ; decrement ECX & jump if
NZloop_exit:
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Building a Loop With an Increasing Loop Index
XOR ECX,ECX ; Set ECX to 0top_of_loop:
...<Register ECX: 0, 1, ... N-1>...INC ECX ; Add 1 to ECXCMP ECX,[iteration_count] ; ECX < count?JB top_of_loop ; Stop if not.
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Application of the Repeated String Instructions
Initialize Memory
Scan Memory Copy MemoryCompare Memory
MOV ECX,[bytes]MOV AL,[value]MOV EDI,[dadrs]CLDREP STOSB
MOV ECX,[bytes]MOV AL,[value]MOV EDI,[dadrs]CLDREP SCASBJE found
MOV ECX,[bytes]MOV ESI,[sadrs]MOV EDI,[dadrs]CLDREP MOVSB
MOV ECX,[bytes]MOV ESI,[sadrs]MOV EDI,[dadrs]CLDREP CMPSBJE identical
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Interfacing to C
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Register Usage ConventionsRegister(s) Usage in C functions
EAXFunctions return all pointers and integer values up to 32‑bits in this register.
EDX and EAX
Functions return 64‑bit values (long long ints) in this register pair. (Note: EDX holds bits 63-32, EAX holds bits 31-0).
EBPUsed to access: (1) The arguments that were passed to a function when it was called, and (2) any automatic variables allocated by the function.
EBX, ESI, EDI, EBP, DS, ES, and SS.
These registers must be preserved by functions written in assembly language. Any of these registers that the function modifies should be saved (PUSH) on entry to the function and restored (POP) on exit.
EAX, ECX, EDX, FS and GS
"Scratch" registers. These registers may be used without preserving their current content.
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Function Call and Return
• CALL instruction used by caller to invoke the function– Pushes the return address onto the stack.
• RET instruction used in function to return to caller.– Pops the return address off the stack.
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
No Parameters and No Return Value.
C prototype: void Disable_Ints(void) ; Example
usage: Disable_Ints() ;
Generated code:
CALL _Disable_Ints
NASM source code
for the function:
_Disable_Ints: CLI ; Disables interrupt system RET ; Return from function
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
No Parameters and 8-bit Return Value.
C prototype: BYTE8 LPT1_Status(void) ; Example
usage: status = LPT1_Status() ;
Generated code:
CALL _LPT1_Status ; returns status in EAX MOV [_status],AL
NASM source code for the
function:
_LPT1_Status: MOV DX,03BDh ; Load DX w/hex I/O adr IN AL,DX ; Get status byte from port. MOVZX EAX,AL ; Zero extend RET ; Return from function.
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Parameter Passing
• Parameters are pushed onto stack prior to CALL.– gcc pushes parameters in reverse order. – 8/16-bit parameters are extended to 32-bits
• Caller removes parameters after function returns.
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Passing Parameters to a C Function
Function call w/parameters: Byte2Port(0x3BC, data) ;
Code generated by the compiler:
PUSH DWORD [_data] ; Push 2nd paramPUSH DWORD 03BCh; Push 1st paramCALL _Byte2Port ; Call the function.ADD ESP,8 ; Remove params
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Passing an 8‑bit Unsigned Integer
C Assembly
unsigned char data ;...Do_Something(data) ;...
MOVZX EAX,[_data] PUSH EAXCALL _Do_SomethingADD ESP,4
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Passing an 8‑bit Signed Integer
C Assembly
signed char data ;...Do_Something(data) ;...
MOVSX EAX,[_data] PUSH EAXCALL _Do_SomethingADD ESP,4
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Passing a 64‑bit Integer
C Assembly
/* signed or unsigned */long long data ; ...Do_Something(data) ;...
PUSH DWORD [_data+4] PUSH DWORD [_data] CALL _Do_SomethingADD ESP,8
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Retrieving Parameters
Address Contents Description [ESP+8] _data The 2nd function parameter (data to write to I/O port) [ESP+4] 03BCh The 1st function parameter (an I/O port address)
[ESP] Return
Address Pushed onto stack by the CALL instruction
Stack immediately after the CALL
PUSH DWORD [_data] ; Push 2nd parameter PUSH DWORD 03BCh ; Push 1st parameterCALL _Byte2Port ; Call the function
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Retrieving Parameters
• Can’t use POP instructions to access parameters.– Parameters expect to be removed from the stack
later by the caller.– RET instruction expects return address to be on
top of the stack.
• Need a way to access parameters without actually removing them from the stack!
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Retrieving Parameters
_Byte2Port:PUSH EBP ; Preserve current contents of EBP on
stackMOV EBP,ESP ; Establish a reference point in the stackMOV DX,[EBP+8]; Copy 1st parameter to DX (the I/O port
address)MOV AL,[EBP+12] ; Copy 2nd parameter to AL (discard bits
15-8)OUT DX,AL ; Write the data to the I/O portPOP EBP ; Restore old contents of EBP from stackRET ; Return to caller
_Byte2Port:MOV DX,[ESP+4] ; Copy 1st parameter to DX (the I/O port
adrs).MOV AL,[ESP+8] ; Copy 2nd parameter to AL (discard bits
31-8).OUT DX,AL ; Write the data to the I/O port.RET ; Return to caller.
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Everything is Pass By Value
Function definition Function invocation
void Swap(int *p1, int *p2){
int temp = *p1 ;*p1 = *p2 ;*p2 = temp ;
}
int x = 4 ;int y = 7 ;…Swap(&x, &y) ;…
Emulating pass-by-reference in C
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Temporary Variables
• Use automatic allocation:– Temporaries rarely need persistence– Allocate temporaries on the stack– Guarantees that function is reentrant
• Only available space is beyond top of stack.– Must be allocated before it can be used (stack
pointer must be adjusted and later restored when temporaries are no longer needed).
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
_Swap: PUSH EBP ; Preserve original EBP contentsMOV EBP,ESP ; Establish stack frame reference in EBPSUB ESP,4 ; Allocate temporary in automatic memory • • •
• • •MOV ESP,EBP ; Release the temporary automatic intPOP EBP ; Restore original EBPRET ; Return from this function
Address Content
s Description
Stack space currently in use by calling context. [EBP+12] p2 [EBP+8] p1
Function parameters pushed on the stack by the caller.
[EBP+4] Return address
Return address pushed by the CALL and popped by the RET.
[EBP] original
EBP Original EBP preserved by PUSH EBP and restored by POP EBP.
[EBP-4] temp Temporary int with automatic memory allocation. (Top of stack)
Unused stack space (Interrupts push return address here)
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
_Swap: PUSH EBP ; Preserve original EBP contentsMOV EBP,ESP ; Establish stack frame reference in EBPSUB ESP,4 ; Allocate a temporary in automatic memory
MOV ECX,[EBP+8] ; temp = *p1: (1) Get 1st parameter (p1)MOV EAX,[ECX] ; (2) Use it to get *p1 into EAXMOV [EBP-4],EAX ; (3) Then store EAX into temp.
MOV ECX,[EBP+12] ; *p1 = *p2: (1) Get 2nd parameter (p2)MOV EAX,[ECX] ; (2) Use it to get *p2 into EAXMOV ECX,[EBP+8] ; (3) Get 1st parameter (p1) againMOV [ECX],EAX ; (4) Use it to store EAX into *p1
MOV EAX,[EBP-4] ; *p2 = temp: (1) Get the temp into EAXMOV ECX,[EBP+12] ; (2) Get 2nd parameter (p2) againMOV [ECX],EAX ; (3) Use it to store EAX into *p2
MOV ESP,EBP ; Release the temporary intPOP EBP ; Restore original EBPRET ; Return from this function
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Optimized Implementation of the Swap Function in Assembly
_Swap:MOV ECX,[ESP+4] ; Copy parameter p1 to ECXMOV EDX,[ESP+8] ; Copy parameter p2 to EDXMOV EAX,[ECX] ; Copy *p1 into EAXXCHG EAX,[EDX] ; Exchange EAX with *p2MOV [ECX],EAX ; Copy EAX into *p1RET ; Return from this function