【发布时间】:2021-07-25 19:54:00
【问题描述】:
给定:
typedef struct __attribute__((packed)) _Node{
int data;
struct _Node *left;
struct _Node *right;
} Node;
以及以下在树中搜索值的汇编代码。 (与How this assembly code will be translated into c?相同的代码)
.section .text
.global _start
_start:
mov $8, %esi
mov $A, %rdi
call func
movq $60, %rax
movq $0, %rdi
syscall
func:
pushq %rbp
movq %rsp, %rbp
cmp (%rdi), %esi
jne continue
mov $1, %eax
jmp finish
continue: # go left
cmpq $0, 4(%rdi)
je next
pushq %rdi # 3
mov 4(%rdi), %rdi
call func
pop %rdi # 4
cmp $1, %eax
je finish
next: # go right
cmpq $0, 12(%rdi)
je fail
pushq %rdi # 1
mov 12(%rdi), %rdi
call func
pop %rdi # 2
cmp $1, %eax
je finish
fail:
mov $0, %rax
finish:
leave
ret
我想知道此更改会产生什么影响以及是否会导致程序无法按预期运行:
在继续后立即添加push %rdi。
据我了解,这会导致问题,因为我们将一些额外的值推送到堆栈中,因此此迭代的调用者可能会弹出错误的 %rdi 值,例如本例中的调用者:
pushq %rdi # 1
mov 12(%rdi), %rdi
call func
pop %rdi # 2
可能会弹出 12+%rdi 而不是弹出 %rdi,但是我运行了很多测试,所有测试似乎都在 RAX 中返回了正确的值,这是为什么呢?
注意:这条线也会导致堆栈溢出吗?我认为答案可能是肯定的。
【问题讨论】:
标签: recursion assembly x86-64 callstack att