CS计算机代考程序代写 assembler compiler x86 assembly Lecture Topics

Lecture Topics
• Calling convention and stack frames
• Application to example
• Misc. x86 instructions
© Steven Lumetta, Zbigniew Kalbarczyk ECE391

The Calling Convention (1)
• What is a calling convention?
– generally: rules for subroutine interface structure
– specifically
• how information is passed into subroutine
• how information is returned to caller
• who owns registers
– often specified by vendor so that different compilers’ code can work together (it’s a CONVENTION)
• Parameters for subroutines – pushed onto stack
– from right to left in C
– order can be language-dependent
© Steven Lumetta, Zbigniew Kalbarczyk ECE391

The Calling Convention (2)
• Subroutine return values – EAX for up to 32 bits
– EDX:EAX for up to 64 bits – floating-point not discussed
• Register ownership
– return values can be clobbered by subroutine: EAX and EDX
– caller-saved: subroutine free to clobber; caller must preserve • ECX
• EFLAGS
– callee-saved: subroutine must preserve value passed in
• stack structure: ESP and EBP
• other registers: EBX, ESI, and EDI
© Steven Lumetta, Zbigniew Kalbarczyk ECE391

Stack Frames in x86 (1)
• The call sequence
0. save caller-saved registers (if desired)
1. push arguments onto stack 2. make the call
3. pop arguments off the stack 4. restore caller-saved registers
© Steven Lumetta, Zbigniew Kalbarczyk ECE391

Stack Frames in x86 (2)
• The callee sequence (creates the stack frame) 0. save old base pointer and get new one
1. save callee-saved registers (always) 2. make space for local variables
3. do the function body
4. tear down stack frame (locals)
5. restore callee-saved registers 6. load old base pointer
7. return
© Steven Lumetta, Zbigniew Kalbarczyk ECE391

Stack Frames in x86 (3)
• Example of caller code (no caller-saved registers considered)
int func (int A, int B, int C);
PUSHL $300 PUSHL $200 PUSHL $100
CALL func
ADDL $12,%ESP
# result in EAX
func (100, 200, 300);
© Steven Lumetta, Zbigniew Kalbarczyk ECE391

Stack Frames in x86 (4)
• Example of subroutine code and stack frame creation and teardown
int func (int A, int B, int C) {
/* 12 bytes of local variables */
… }
call func (100, 200, 300);
© Steven Lumetta, Zbigniew Kalbarczyk ECE391

Stack Frames in x86 (4)
PUSHL %EBP
MOVL %ESP,%EBP
SUBL $12,%ESP
(body)
LEAVE
ESP EBP
local
vars.
old EBP
ret. addr
A=100
B=200
C=300
ret. addr
A=100
B=200
C=300
ESP
(old frame) EBP
stack on entry to function
© Steven Lumetta, Zbigniew Kalbarczyk
RET stack during function body
ESPEBP+4, EBPM[EBP] ECE391

Subroutine Example Code
• Earlier assumptions
– some values start in registers (array pointer in EBX, length in ECX) – could specify output regs (min. age in EDX, max. age in EDI)
array of
As a C function, we could write…
void find_min_max (person* group, long n_people,
min_max* mm)
char* name
long age
long min
long max
© Steven Lumetta, Zbigniew Kalbarczyk ECE391

{ step 1: create the stack frame PUSHL %EBP
(no local vars.)
Subroutine Example Code (cont.)
MOVL %ESP,%EBP
PUSHL %EBX # protect callee-saved
ESP
EBP
(EDI)
(ESI)
(EBX)
old EBP
ret. address
group
n_people
mm
PUSHL %ESI
PUSHL %EDI
# registers
step 2: link to our input interface
MOVL 8(%EBP),%EBX # group
MOVL 12(%EBP),%ECX # n_people step 3: insert our code from before
step 4: link from our output interface
MOVL 16(%EBP),%EBX # load mm into EBX MOVL %EDX,0(%EBX) # mm <- min MOVL %EDI,4(%EBX) #(mm + 4) <- max step 5: tear down stack frame Subroutine Example Code (cont.) # we have no local variables to remove # restore callee-saved registers #(note that order is reversed!) POPL %EDI POPL %ESI POPL %EBX LEAVE RET alternate version (used by gcc) LEAL -12(%EBP),%ESP POPL %EDI POPL %ESI POPL %EBX POPL %EBP RET (no local vars.) ESP EBP (EDI) (ESI) (EBX) old EBP ret. address group n_people mm © Steven Lumetta, Zbigniew Kalbarczyk ECE391 Multiplication and Division MULL %EBX # unsigned EDX:EAX  EAX * EBX IMULL %EBX # signed (as above) # multiple-operand forms are ONLY for signed operations IMULL IMULL %ECX,%EBX # signed EBX  EBX * ECX (high bits discarded) $20,%EDX,%ECX # signed ECX  20 * EDX (high bits discarded) quotient dividend %EBX # unsigned EAX  EDX:EAX / EBX DIV IDIV ... # (signed version) © Steven Lumetta, Zbigniew Kalbarczyk ECE391 # EDX  remainder Data Type Alignment (1) • Memory addresses – when loading data from or storing data to memory – use address that is multiple of size of data • Examples – for bytes, use any address – for words (16-bit), use even addresses only (multiple of 2 bytes) – for longs (32-bit), use multiple-of-4 addresses only © Steven Lumetta, Zbigniew Kalbarczyk ECE391 • Data Type Alignment (2) Rationale: simplifies implementation of processor-memory interface – required by many modern ISAs – optional on x86 (but very slow if you don’t align) – x86 has alignment check flag (AC), but usually turned off Use “.ALIGN 4” (number is an argument) to align x86 assembly – for x86 assemblers, you can even do so in the middle of code • © Steven Lumetta, Zbigniew Kalbarczyk ECE391 Device I/O • How does a processor communicate with devices? • Two possibilities – independent I/O — use special instructions and a separate I/O port address space – memory-mapped I/O — use loads/stores and dedicate part of the memory address space to I/O • x86 originally used only independent I/O – but when used in PC, needed a good interface to video memory – solution? put card on the bus, claim memory addresses! – now uses both, although ports are somewhat deprecated © Steven Lumetta, Zbigniew Kalbarczyk ECE391