assembly 07. outline boxes within boxes procedure definition call, ret saving / restoring registers...
TRANSCRIPT
Assembly 07
2
Outline
• Boxes within Boxes• Procedure Definition• call, ret• Saving / Restoring Registers• Argument(s)• Return Value(s)• Global vs. Local Data• Accidental Recursion
3
Boxes within Boxes
• Procedures help manage code complexity• Procedures make code more:
• Readable• Maintainable• Reusable
What does this code do
again?
4
Boxes within Boxes
• Unlike high-level languages, assembly does not “ship” with built-in procedures (e.g., printf in C++)
• You have to write your own procedures• Read from file• Write to file• Etc.
5
Boxes within Boxes
• Book uses example of “getting up in the morning”• Shut off clock radio• Climb out of bed• Let dogs out• Eat breakfast• Brush your teeth• Shower
6
Boxes within Boxes
• Each task can be divided into smaller tasks:• E.g., Brushing your teeth:
• Pick up toothpaste• Unscrew cap• Place cap on sink counter• …
• Same idea with procedures• Divide tasks into subtasks
7
Outline
• Boxes within Boxes• Procedure Definition• call, ret• Saving / Restoring Registers• Argument(s)• Return Value(s)• Global vs. Local Data• Accidental Recursion
8
Procedure Definition
• Must begin with a label• Must have at least one ret (return)• E.g.,
my_print: ; label for “my_print” proc<instruction> ; some instruction<instruction> ; some instructionret ; return
9
Outline
• Boxes within Boxes• Procedure Definition• call, ret• Saving / Restoring Registers• Argument(s)• Return Value(s)• Global vs. Local Data• Accidental Recursion
10
call Mnemonic
call -> used to invoke the procedure
usage: call <procedure_name>;
11
ret Mnemonic
ret -> returns from procedure
usage:ret ; takes no operands
; returns to instruction after call
12
call / ret Mnemonics
• call puts esp onto stack• esp has address of next instruction (after call)
• ret pops esp from stack• Execution resumes at the instruction after call
13
my_print:
<instruction>;
<instruction>;
ret;
<instruction>;
call my_print;
<next instr>;
…
stack
esp
1. instruction executes
14
my_print:
<instruction>;
<instruction>;
ret;
<instruction>;
call my_print;
<next instr>;
…
stack
esp
2. call to my_print made
15
my_print:
<instruction>;
<instruction>;
ret;
<instruction>;
call my_print;
<next instr>;
…
stack
esp
3. esp+1 value pushed to stack
address of <next instr>;
16
my_print:
<instruction>;
<instruction>;
ret;
<instruction>;
call my_print;
<next instr>;
…
stack
esp
4. flow of execution goes to my_print
address of <next instr>;
17
my_print:
<instruction>;
<instruction>;
ret;
<instruction>;
call my_print;
<next instr>;
…
stack5. my_print executes address of <next instr>;
esp
18
my_print:
<instruction>;
<instruction>;
ret;
<instruction>;
call my_print;
<next instr>;
…
stack6. ret (return) reached in my_print
address of <next instr>;
esp
19
my_print:
<instruction>;
<instruction>;
ret;
<instruction>;
call my_print;
<next instr>;
…
stack7. Address popped off stack
8. esp set to address
address of <next instr>;
esp
20
my_print:
<instruction>;
<instruction>;
ret;
<instruction>;
call my_print;
<next instr>;
…
stack9. Flow of execution continues at instruction after call
esp
21
my_print:
<instruction>;
<instruction>;
ret;
<instruction>;
call my_print;
<next instr>;
…
stack10. Flow of execution continues…
esp
22
stack
Every time you make a call, the stack grows by 32 bits.
Why??
return address
return address
return address
return address
return address
23
stack
Every time you return from a procedure (with ret), the stack shrinks by 32 bits.
return address
return address
return address
msg: db “Hello There!!!”,10 ; in .datamsgLen: equ $-msg ; in .data
call my_print ; in .textcall my_print ; in .textcall my_print ; in .text
my_print: ; in .textmov eax, 4 ; make sys_write callmov ebx, 1 ; write to stdoutmov ecx, msg ; write contents of msgmov edx, msgLen ; number of bytes to write int 0x80 ; make system callret ; return
25
call / ret Mnemonics
UNIX> ./a.outHello World!!!Hello World!!!Hello World!!!UNIX>
msg: db “Hello There!!!”,10msgLen: equ $-msg call my_printcall my_printcall my_print
my_print:mov eax, 4mov ebx, 1mov ecx, msgmov edx, msgLenint 0x80ret
26
Outline
• Boxes within Boxes• Procedure Definition• call, ret• Saving / Restoring Registers• Argument(s)• Return Value(s)• Global vs. Local Data• Accidental Recursion
27
Saving Register Values
• What is the result of add eax, ebx?
mov eax, 42;mov ebx, 58;call my_print;add eax, ebx;
28
Saving Register Values
mov eax, 42;mov ebx, 58;call my_print;add eax, ebx;
eax
ebx
29
Saving Register Values
mov eax, 42;mov ebx, 58;call my_print;add eax, ebx;
42
58
eax
ebx
30
Saving Register Values
mov eax, 42;mov ebx, 58;call my_print;add eax, ebx;
4
1
eax
ebx
my_print sets eax to “4” for sys_write
my_print sets ebx to “1” for stdout
31
Saving Register Values
mov eax, 42;mov ebx, 58;call my_print;add eax, ebx;
5
1
eax
ebx
were we expecting “5” or “100”??
32
Saving Register Values
• Often important to save registers before calling a procedure
• Guards against bugs that are extremely hard to track down
spooky
33
Saving Register Values
• Use the stack to save registers• Push registers onto stack before procedure call• Pop registers off of stack after procedure returns
• Be mindful of order!• Last In First Out
34
Saving Register Values
• If you “own” the procedure code, you can push / pop registers within the procedure
• Push registers at beginning of procedure
• Pop registers at end of procedure
35
Saving Register Values
mov eax, 42;mov ebx, 58;pushad;call my_print;popad;add eax, ebx;
eax
ebx
36
Saving Register Values
mov eax, 42;mov ebx, 58;pushad;call my_print;popad;add eax, ebx;
42
58
eax
ebx
37
Saving Register Values
mov eax, 42;mov ebx, 58;pushad;call my_print;popad;add eax, ebx;
42
58
eax
ebx
all 32-bit GP registers pushed to stack
38
Saving Register Values
mov eax, 42;mov ebx, 58;pushad;call my_print;popad;add eax, ebx;
4
1
eax
ebx
39
Saving Register Values
mov eax, 42;mov ebx, 58;pushad;call my_print;popad;add eax, ebx;
42
58
eax
ebx
pop all 32-bit registers from stack back to registers
40
Saving Register Values
mov eax, 42;mov ebx, 58;pushad;call my_print;popad;add eax, ebx;
100
58
eax
ebx
41
Outline
• Boxes within Boxes• Procedure Definition• call, ret• Saving / Restoring Registers• Argument(s)• Return Value(s)• Global vs. Local Data• Accidental Recursion
42
Passing Arguments
• How do you pass arguments to assembly procedures?• … and no, this is not a setup for a hilarious joke…
• Use registers!• Caller puts arguments into pre-ordained registers• E.g., eax is argument 1, ebx is argument 2, etc.
• Important to clearly comment your procedures!!• Especially expectations for arguments• E.g., integer in eax, pointer in ebx, etc.
43
Passing Arguments
• Example: procedure to add two numbers, print result to stdout• Numbers will be arguments to procedure
• Simplified version: only prints results between 0 and 9…• Printing results > 10 may be part of your homework…
SIZE: equ 10 ; in .dataoutput: resb SIZE ; in .bss
; below in .textmov eax, 2 ; argument 1 in eaxmov ebx, 3 ; argument 2 in ebxcall my_add ; invoke procedure to add/print
my_add: ; procedure to add / print resultadd eax, ebx ; add argumentsadd eax, ‘0’ ; convert to ASCII numbermov [output], eax; ; put result in output buffermov byte [output+1], 10 ; add carriage returncall my_print ; write output buffer to stdoutret ; return to caller
45
Procedure Arguments
UNIX> ./a.out5UNIX>
msg: SIZE: equ 10output: resb SIZE
mov eax, 2mov ebx, 3call my_add
my_add:add eax, ebxadd eax, ‘0’mov [output], eaxmov byte [output+1], 10 call my_printret
46
Outline
• Boxes within Boxes• Procedure Definition• call, ret• Saving / Restoring Registers• Argument(s)• Return Value(s)• Global vs. Local Data• Accidental Recursion
47
Return Value(s)
• How do you return value(s) from assembly procedures?
• Register(s), of course!!
• Example: convert character from lowercase to uppercase
mov al, ‘a’ ; argument 1 in alcall convert ; convert ‘a’ to ‘A’
; cl now has converted
covert: ; procedure to convertmov cl, al ; copy argument 1sub cl, 32 ; make return value uppercase
; (‘A’ is 32 less than ‘a’)ret ; return to caller
mov al, ‘a’;call convert;
covert:mov cl, alsub cl, 32ret
al
cl
mov al, ‘a’;call convert;
covert:mov cl, alsub cl, 32ret
96 = 0x61 = ‘a’al
cl
mov al, ‘a’;call convert;
covert:mov cl, alsub cl, 32ret
96 = 0x61 = ‘a’al
cl
mov al, ‘a’;call convert;
covert:mov cl, alsub cl, 32ret
96 = 0x61 = ‘a’
96 = 0x61 = ‘a’
al
cl
mov al, ‘a’;call convert;
covert:mov cl, alsub cl, 32ret
96 = 0x61 = ‘a’
65 = 0x41 = ‘A’
al
cl
mov al, ‘a’;call convert;
covert:mov cl, alsub cl, 32ret
96 = 0x61 = ‘a’
65 = 0x41 = ‘A’
al
cl
now cl has return value ‘A’
55
Outline
• Boxes within Boxes• Procedure Definition• call, ret• Saving / Restoring Registers• Argument(s)• Return Value(s)• Global vs. Local Data• Accidental Recursion
56
Global vs. Local Data
• Global: can be accessed anywhere in code• Local: can only be accessed “locally” (e.g., within procedure)
• In x86 assembly, all declared data items are global• Can declare data items in .text (!!!)
• Appear local, but actually global
57
Examples of Local Data
• Using the stack to temporarily store data in procedures• Data pushed to stack (during procedure) only visible to that procedure
• Data items declared in external code libraries• Only visible to external code • (But there is a mechanism to make global)
58
Outline
• Boxes within Boxes• Procedure Definition• call, ret• Saving / Restoring Registers• Argument(s)• Return Value(s)• Global vs. Local Data• Accidental Recursion
59
Accidental Recursion
• “Uncommon but inevitable bug”
• Watch out for incorrect base case• Pay attention to instruction => flags
• Will eventually run out of stack space• Each call pushes 32-bits onto stack (Why?)• Eventually causes a Segmentation Fault (Why?)
60
Accidental Recursion Example
• “Not so accidental” recursion
call recur; ; 1st instruction in .text ; after _start
recur:call my_print ; call procedure to print “LINE”call recur ; make recursive callret ; never reached..
61
Accidental Recursion Example
UNIX> ./a.outLINELINELINELINELINE... (on and on..)Segmentation FaultUNIX>
call recur;
recur:call my_printcall recurret
stdout in BLUEstderr in GREEN
62
Accidental Recursion Example
UNIX> ./a.out > output.txtSegmentation FaultUNIX> head –n 2 output.txtLINELINEUNIX> wc –l output.txt 2094543 output.txt
63
Accidental Recursion Example
UNIX> ./a.out > output.txtSegmentation FaultUNIX> head –n 2 output.txtLINELINEUNIX> wc –l output.txt 2094543 output.txt
> : redirect stdout to a file named “output.txt”
stderr ignored
64
Accidental Recursion Example
UNIX> ./a.out > output.txtSegmentation FaultUNIX> head –n 2 output.txtLINELINEUNIX> wc –l output.txt 2094543 output.txt
head –n 2 output.txt : output top 2 lines of file output.txtoutput.txt contains “LINE” printed once per line
65
Accidental Recursion Example
UNIX> ./a.out > output.txtSegmentation FaultUNIX> head –n 2 output.txtLINELINEUNIX> wc –l output.txt 2094543 output.txt
wc –l output.txt :count number of lines in file output.txt
output.txt contains 2,094,543 lines.recur called 2+ million times!!