Stack Pointer/Frame Pointer

Stack Frame

fil

firstly, callee stack save the old caller ‘s stack ‘s ebp

lastly, the argument build means the arguments for calling any other function

upload successfl

pushl $zip2,$zip1 把参数压进栈顶,然后call swap,会把caller的return address压入栈

whole code

upload succesful

set up code

filename already exists, amed

一. push %ebp 把caller的 bast pointer 的数值压栈

二.movl %esp,%ebp (把esp 移动到ebp,即设置ebp = esp,这一步是设置callee的base pointer)

三.%ebx 是swap过程中可能会调用的参数

https://www.cnblogs.com/qq78292959/archive/2012/07/20/2600865.html

附上:EAX 是”累加器”(accumulator), 它是很多加法乘法指令的缺省寄存器。

EBX 是”基地址”(base)寄存器, 在内存寻址时存放基地址。

ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。

EDX 则总是被用来放整数除法产生的余数。

但是对于 %eax,%ecx,%edx 不能像ebx一样,保存在callee中

body code

upload successfl

finish code

upload sucu

  1. %ebp-4 就是 old %ebx 的地址 ,把-4(%ebp)移到%ebx,相当于把原来的%ebx复原

2.第二是 把 %ebp 移到 %esp,即现在%esp指向%ebp

(第一第二条指令相当于 pop %ebx)
upload successf

3.popl %ebp
本质上是

1
2
0(%esp),%ebp 
%esp +4

这个时候base pointer复原,变回caller stack 的数值

4.ret 根据返回地址返回

其中leave instruction
等价于
mov %ebp,%esp

popl %ebp

register saving convention

upload succesul

yoo当中,我们希望%edx不会因为调用了who函数之后发生改变,问题是,who调用过程中,%edx是可能发生改变的。

因此我们要制定convention,在使用这些寄存器之前先保存他们!

filename already exists, rnamed

分类如下
fileame already exists, renamed

%eax save the return address so it is caller saved register

example

filename already exis, renamed

upload successf

1
2
3
4
5
6
7
8
9
1.pushl %ebp #save the caller's ebp

2.movl %esp,%ebp #set callee's ebp

3.subl $16,%esp # add 16 bytes, add temporary space

4.movl 8(%ebp),%edx # set edx = x

5.movl $1,-4(%ebp)

filename already eists, renamed

两个pushl 相当于把 s_helper函数的两个参数传了进去

&val始终指向val,当函数结束的时候,返回的值就保存在了-4(%ebp)当中

upload sucessful

Summary

1.若调用函数有多个参数,stack从下到上,依次为第一个,第二个函数。

2.函数调用的参数在stack的上方,就是在caller准备好参数后再调用callee,就是说argument 是caller saved 的

3.函数结果返回在%eax

4.local variable 是存放在 callee-saved registers那里

x86-64 conventions

在x86 中,由于registers 的数目变多,因此可以把local variable 和argument存储在register当中,那样就可以减少对stack 的使用了

下图是16个 8-byte gpr
filename exists, rena

黄色的是caller saved

绿色的是 callee saved

specifications

up

1.用callq 而不用call,因为要返回一个64-bit address,also decrement 8而不是4(8 bytes)

2.因为gpr实现了ebp / rbp 功能,因此不需要使用stack来更新 ,而且rsp能代替实现frame pointer 的功能

3.由于gpr只有6个argument register,所以当函数参数少于六个的时候,不需要用到栈结构

example

upload successfu

q - 8byte - 64bits

l - 4byte - 32bits

w - 2byte - 16bits

b - 1byte - 8bits

filename already exists, rena

prepare for the arguments

1
2
3
4
5
6
7
8
9
movq $1,%rdi
leaq 16(%rsp),%rsi
movl $2,%rdx
leaq 24(%rsp),%rcx
movl $3,%r8
leaq 28(%rsp),%r9
movl $4,(%rsp) #Arg 7
leaq 31(%rsp),%rax
movq %rax,8(%rsp) #Arg 8

upload succesul

1
2
3
4
5
movswl 28(%rsp),%eax # %eax = x3

movsbl 31(%rsp),%edx # %edx = x4

s 表示 signextend