调用指令破坏堆栈
call instruction destroying stack
我正在用汇编代码编写一个基本程序,旨在打印数字 1-10。我的目标是在堆栈上分配两个变量,一个是计数器,另一个是最终目的地。我想比较它们,打印它们,增加计数器。
我遇到的问题是,当我调用函数 printf 时,returns 它正在清除堆栈。我没有做任何类型的堆栈溢出或任何事情。我不明白为什么调用 printf
会破坏 $rsp-0x10
和 $rsp-0x20
处的堆栈
global main
extern printf
section .text
main:
push rbp
mov rbp, rsp
sub rsp, 0x20
mov qword [rsp-0x10], 0x0
mov qword [rsp-0x20], 0xA
looper:
mov rax, [rsp-0x10] ; load the value on the stack (var 1) into the rax register
inc rax ; increment the register
mov qword [rsp-0x10],rax ; copy the new value back to the stack
mov rdi, message ; load the address of the message string
mov rsi, rax ; load the second parameter which is the value of the counter var
call printf ; call printf. After this instruction the values at $rsp-0x10 and $rsp-0x20 are zero
mov rax, [rsp-0x10] ; ideally I would load the vars back up into rax and rbx
mov rbx, [rsp-0x20]
cmp rax, rbx ; then compare the variables and loop if they are not equal
jne looper
done:
leave
ret
section .data
message: db “%d”, 10, 0
您只能在叶函数(不调用其他函数)中使用红色区域。很明显,如果你发出一个 call
,它本身已经把一个 return 地址放在堆栈上,然后被调用的函数也可以使用堆栈,就像你被允许使用它一样。
仔细一看,我认为您只是搞砸了基址寄存器,您想使用 rbp
而不是 rsp
进行寻址,因为您在堆栈帧中分配了 space。 space 低于 rbp
但高于 rsp
。
PS:rbx
是一个被调用者保存的寄存器,你应该保留它的值。
PS #2:根据调用约定,可变参数函数期望 al
中使用的向量寄存器数量的上限。由于 printf
是这样一个函数,因此在调用它之前应将 al
归零。
我正在用汇编代码编写一个基本程序,旨在打印数字 1-10。我的目标是在堆栈上分配两个变量,一个是计数器,另一个是最终目的地。我想比较它们,打印它们,增加计数器。
我遇到的问题是,当我调用函数 printf 时,returns 它正在清除堆栈。我没有做任何类型的堆栈溢出或任何事情。我不明白为什么调用 printf
会破坏 $rsp-0x10
和 $rsp-0x20
global main
extern printf
section .text
main:
push rbp
mov rbp, rsp
sub rsp, 0x20
mov qword [rsp-0x10], 0x0
mov qword [rsp-0x20], 0xA
looper:
mov rax, [rsp-0x10] ; load the value on the stack (var 1) into the rax register
inc rax ; increment the register
mov qword [rsp-0x10],rax ; copy the new value back to the stack
mov rdi, message ; load the address of the message string
mov rsi, rax ; load the second parameter which is the value of the counter var
call printf ; call printf. After this instruction the values at $rsp-0x10 and $rsp-0x20 are zero
mov rax, [rsp-0x10] ; ideally I would load the vars back up into rax and rbx
mov rbx, [rsp-0x20]
cmp rax, rbx ; then compare the variables and loop if they are not equal
jne looper
done:
leave
ret
section .data
message: db “%d”, 10, 0
您只能在叶函数(不调用其他函数)中使用红色区域。很明显,如果你发出一个 call
,它本身已经把一个 return 地址放在堆栈上,然后被调用的函数也可以使用堆栈,就像你被允许使用它一样。
仔细一看,我认为您只是搞砸了基址寄存器,您想使用 rbp
而不是 rsp
进行寻址,因为您在堆栈帧中分配了 space。 space 低于 rbp
但高于 rsp
。
PS:rbx
是一个被调用者保存的寄存器,你应该保留它的值。
PS #2:根据调用约定,可变参数函数期望 al
中使用的向量寄存器数量的上限。由于 printf
是这样一个函数,因此在调用它之前应将 al
归零。