如何理解调用函数时堆栈指针改变的字节

问题描述 投票:0回答:1

我对调用 callq 或 retq 时堆栈指针更改的字节感到困惑? 这是一个小例子

;  Disassembly of leaf (long y) y in %rdi
0000000000400540 <leaf>:
400540: 48 8d 47 02   lea 0x2 (%rdi) ,%rax ; L1: y+2
400544:с3 retq                             ; L2: Return

0000000000400545 <top>:
;  Disassembly of top(long x) x in %rdi
400545: 48 83 ef 05 sub $0x5,%rdi          ; T1: x-5
400549: e8 f2 ff ff ff callq 400540 <leaf> ; T2: Call leaf (x-5)
40054e: 48 01 c0 add %rax,%rax             ; T3: Double result
400551: с3 retq                            ; T4: Return

;  Call to top from function main
40055b: e8 e5 ff ff ff callq 400545 <top>  ; M1: Call top (100)
400560:48 89 c2 mov %rax,%rdx              ; M2: Resume
       Pc             %rdi   %rax      %rsp           *%rsp 

M1  0×400556   callq   100         0x7fffffffe820
T1  0×400545   sub     100         0x7fffffffe818    0х400560
T2  0×400549   callq    95         0x7fffffffe818    0×400560
L1  0×400540   lea      95         0x7fffffffe810    0x40054e
L2  0×400544   retq            97  0x7fffffffe810    0x40054e
T3  0x40054e   add             97  0x7fffffffe818    0×400560
T4  0x400551   Retq           194  0x7fffffffe818    0×400560
M2  0x400560   Mov            194  0x7fffffffe820

为什么调用第一个函数时堆栈指针小于 2 个字节,而调用第二个函数时堆栈指针小于 8 个字节

我想知道两者差异的原因,下次遇到这种情况时,如何知道堆栈指针变化的字节数。

assembly stack x86-64 att stack-pointer
1个回答
0
投票

它不小于 2 个字节。它是十六进制的,所以从 0x20 到 0x18 需要减去 8,而不是 2。(如果只减去 2,结果将以 0x1E 结尾)

0x7fffffffe820 = 140737488349216
0x7fffffffe818 = 140737488349208 (-8)
0x7fffffffe810 = 140737488349200 (-8)
© www.soinside.com 2019 - 2024. All rights reserved.