Transcript COEN 020
CHAPTER 5
MIXING C AND ASSEMBLY
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
The Four Fields of a Line of
Code in Assembly Language
Operation
Field
L1:
MOV EAX,[RESULT+2]
Label
Field
Operand
Fields
; load selected table element
Comment
Field
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Use of “[…]” in NASM Assembler
xyzzy:
ORG 1234h
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
...
...
MOV
AL,[X+2]
DB 5,7,3
...
3F3A 05 07 …
...
Symbol Table
X
Assembler Pass 2
X
Assembler Pass 1
...
1B27 A0 &x+2
...
...
3F3A
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
1B27 A0 3F3C
...
3F3A 05 07 …
...
Instruction Sequencing
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Code Generated by Compiler for
Break and End of Loop
for (;;)
{
...
if (...) break ;
...
}
top_of_for:
...
...
JMP end_of_for
...
JMP top_of_for
end_of_for: ...
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Commonly-Used Conditional
Jump Instructions
Compare
equality
unsigned
signed
Mnemonic(s)
Jump if . . .
Determined by . . .
JE (JZ)
Equal (Zero)
ZF==1
JNE (JNZ)
Not Equal (Not Zero)
ZF==0
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
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:
end_of_while:
CMP
JNL
...
JMP
DWORD [x],1000
end_of_while
top_of_while
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Compound Conditionals
if (lower_limit <= x && x <= upper_limit) y = x ;
L1:
L1:
L1:
if (!(lower_limit <= x && x <= upper_limit)) goto L1
y=x;
if (x < lower_limit || x > upper_limit) goto L1
y=x;
if (x < lower_limit) goto L1
if (x > upper_limit) goto L1
y=x;
MOV
CMP
JL
CMP
JG
MOV
L1:
EAX,[x]
EAX,[lower_limit]
L1
EAX,[upper_limit]
L1
[y],EAX
...
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Compound Conditionals
if (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:
MOV
CMP
JL
CMP
JNG
L1: MOV
L2: ...
EAX,[x]
EAX,[lower_limit]
L1
EAX,[upper_limit]
L2
[y],EAX
if (x < lower_limit) goto L1
if (!(x > upper_limit)) goto L2
L1: y = x ;
L2:
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
If-Then-Else Statements
if (x > y)
{
x=0;
}
else
{
y=0;
}
L1:
L2:
MOV
CMP
JNG
MOV
JMP
MOV
...
EAX,[x]
;x>y?
EAX,[y]
L1
DWORD [x],0 ; then: x = 0 ;
L2
; skip over else
DWORD [y],0 ; else: y = 0 ;
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 NZ
loop_exit:
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Building a Loop With an
Increasing Loop Index
top_of_loop:
XOR
ECX,ECX
...
<Register ECX: 0, 1, ... N-1>
...
INC ECX
CMP ECX,[iteration_count]
JB
top_of_loop
; Set ECX to 0
; Add 1 to ECX
; ECX < count?
; Stop if not.
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Application of the Repeated
String Instructions
Initialize Memory
MOV
MOV
MOV
CLD
REP
ECX,[bytes]
AL,[value]
EDI,[dadrs]
STOSB
Scan Memory
MOV
MOV
MOV
CLD
REP
JE
ECX,[bytes]
AL,[value]
EDI,[dadrs]
SCASB
found
Copy Memory
MOV
MOV
MOV
CLD
REP
ECX,[bytes]
ESI,[sadrs]
EDI,[dadrs]
MOVSB
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Compare Memory
MOV
MOV
MOV
CLD
REP
JE
ECX,[bytes]
ESI,[sadrs]
EDI,[dadrs]
CMPSB
identical
Interfacing to C
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Register Usage Conventions
Register(s)
EAX
EDX and
EAX
EBP
EBX, ESI,
EDI, EBP,
DS, ES, and
SS.
EAX, ECX,
EDX, FS
and GS
DS, ES, SS,
EBP, and
ESP
Usage in C functions
Functions return all pointers and integer values up to 32-bits in this
register.
Functions return 64-bit values (long long ints) in this register pair.
(Note: EDX holds bits 63-32, EAX holds bits 31-0).
Used to access: (1) The arguments that were passed to a function
when it was called, and (2) any automatic variables allocated by the
function.
These registers must be preserved by functions written in assembly
language. Any of these registers that the function modifies should be
pushed on entry to the function and popped on exit.
"Scratch" registers. These registers may be used without preserving
their current content.
Used to reference data. If modified by a function, the current
Copyright
© 2000,
Daniel W. must
Lewis. be
All Rights
Reserved.
contents
of these
registers
preserved
on entry and restored
on return.
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:
Example
usage:
Generated
code:
void Disable_Ints(void) ;
Disable_Ints() ;
CALL
NASM _Disable_Ints:
source code
CLI
RET
for the
function:
_Disable_Ints
; Disables interrupt system
; Return from function
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
No Parameters and 8-bit Return Value.
C prototype:
Example
usage:
Generated
code:
BYTE8
LPT1_Status(void) ;
status = LPT1_Status() ;
CALL
MOV
_LPT1_Status:
MOV
NASM source
XOR
code for the
IN
function:
RET
_LPT1_Status ; returns status in EAX
[_status],AL
DX,03BDh
EAX,EAX
AL,DX
; Load DX w/hex I/O adr
; Pre-Zero rest of EAX
; Get status byte from port.
; 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:
Code generated by
the compiler:
Byte2Port(0x3BC, data) ;
PUSH
MOV
PUSH
CALL
ADD
DWORD [_data]
EAX,03BCh
EAX
_Byte2Port
ESP,8
; Push 2nd param
; Push 1st param
; Call the function.
; 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
PUSH
CALL
ADD
EAX,[_data]
EAX
_Do_Something
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
PUSH
CALL
ADD
EAX,[_data]
EAX
_Do_Something
ESP,4
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Passing a 64-bit Integer
C
/* signed or unsigned */
long long data ;
...
Do_Something(data) ;
...
Assembly
PUSH
PUSH
CALL
ADD
DWORD [_data+4]
DWORD [_data]
_Do_Something
ESP,8
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Retrieving Parameters
PUSH
MOV
PUSH
CALL
Address
[ESP+8]
[ESP+4]
[ESP]
DWORD [_data]
EAX,03BCh
EAX
_Byte2Port
; Push 2nd parameter
; Push 1st parameter
; onto the stack.
; Call the function
Stack immediately after the CALL
Contents Description
_data The 2nd function parameter (data to write to I/O port)
03BCh The 1st function parameter (an I/O port address)
Return
Pushed onto stack by the CALL instruction
Address
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:
MOV
MOV
OUT
RET
_Byte2Port:
PUSH
MOV
MOV
MOV
OUT
POP
RET
DX,[ESP+4]
AL,[ESP+8]
DX,AL
EBP
EBP,ESP
DX,[EBP+8]
AL,[EBP+12]
DX,AL
EBP
;
;
;
;
Copy 1st parameter to DX (the I/O port adrs).
Copy 2nd parameter to AL (discard bits 31-8).
Write the data to the I/O port.
Return to caller.
; Preserve current contents of BP on stack
; Establish a reference point in the stack
; Copy 1st parameter to DX (the I/O port address)
; Copy 2nd parameter to AL (discard bits 15-8)
; Write the data to the I/O port
; Restore old contents of BP from stack
; Return to caller
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
Everything is Pass By Value
Function definition
void Swap(int *p1, int *p2)
{
int temp = *p1 ;
*p1 = *p2 ;
*p2 = temp ;
}
Function invocation
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
MOV
SUB
•••
EBP
EBP,ESP
ESP,4
Content
s
[EBP+12]
p2
[EBP+8]
p1
Return
[EBP+4]
address
original
[EBP]
EBP
Address
[EBP-4]
temp
; Preserve original EBP contents
; Establish stack frame reference in EBP
; Allocate temporary in automatic memory
Description
Stack space currently in use by calling context.
Function parameters pushed on the stack by the caller.
Return address pushed by the CALL and popped by the RET.
Original EBP preserved by PUSH EBP and restored by POP
EBP.
Temporary int with automatic memory allocation. (Top of
stack)
Unused stack space (Interrupts push return address here)
•••
MOV ESP,EBP
POP
EBP
RET
; Release the temporary automatic int
; Restore original EBP
; Return from this function
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.
_Swap: PUSH
MOV
SUB
EBP
EBP,ESP
ESP,4
; Preserve original EBP contents
; Establish stack frame reference in EBP
; Allocate a temporary in automatic memory
MOV
MOV
MOV
ECX,[EBP+8]
EAX,[ECX]
[EBP-4],EAX
; temp = *p1:
;
;
(1) Get 1st parameter (p1)
(2) Use it to get *p1 into EAX
(3) Then store EAX into temp.
MOV
MOV
MOV
MOV
ECX,[EBP+12]
EAX,[ECX]
ECX,[EBP+8]
[ECX],EAX
; *p1 = *p2:
;
;
;
(1) Get 2nd parameter (p2)
(2) Use it to get *p2 into EAX
(3) Get 1st parameter (p1) again
(4) Use it to store EAX into *p1
MOV
MOV
MOV
EAX,[EBP-4] ; *p2 = temp:
ECX,[EBP+12] ;
[ECX],EAX
;
MOV
POP
RET
ESP,EBP
EBP
(1) Get the temp into EAX
(2) Get 2nd parameter (p2) again
(3) Use it to store EAX into *p2
; Release the temporary int
; Restore original EBP
; 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 ECX
MOV EDX,[ESP+8] ; Copy parameter p2 to EDX
MOV EAX,[ECX] ; Copy *p1 into EAX
XCHG EAX,[EDX] ; Exchange EAX with *p2
MOV [ECX],EAX ; Copy EAX into *p1
RET
; Return from this function
Copyright © 2000, Daniel W. Lewis. All Rights Reserved.