gpt4 book ai didi

c - About Variable-Size Stack Frames,关于栈帧的对齐,来自CSAPP的一个例子

转载 作者:行者123 更新时间:2023-12-05 05:15:21 29 4
gpt4 key购买 nike

C代码:

long vframe(long n, long idx, long *q) {
long i;
long *p[n];
p[0] = &i;

for (i = 1; i < n; i++)
p[i] = q;

return *p[idx];
}

部分生成的汇编代码:

long vframe(long n, long idx, long *q)

n in %rdi, idx in %rsi, q in %rdx
Only portions of code shown
vframe:
pushq %rbp Save old %rbp
movq %rsp, %rbp Set frame pointer
subq $16, %rsp Allocate space for i (%rsp = s1)
leaq 22(,%rdi,8), %rax
andq $-16, %rax
subq %rax, %rsp Allocate space for array p (%rsp = s2)
leaq 7(%rsp), %rax
shrq $3, %rax
leaq 0(,%rax,8), %r8 Set %r8 to &p[0]
movq %r8, %rcx Set %rcx to &p[0] (%rcx = p)
...
Code for initialization loop
i in %rax and on stack, n in %rdi, p in %rcx, q in %rdx
.L3: loop:
movq %rdx, (%rcx,%rax,8) Set p[i] to q
addq $1, %rax Increment i
movq %rax, -8(%rbp) Store on stack
.L2:
movq -8(%rbp), %rax Retrieve i from stack
cmpq %rdi, %rax Compare i:n
jl .L3 If <, goto loop
...
Code for function exit
leave Restore %rbp and %rsp
ret Return

作者在书中说:

leaq指令在

leaq    22(,%rdi,8), %rax

计算值 8n + 22,然后通过 andq 指令向下舍入到最接近的 16 的倍数

andq    $-16, %rax

n 为奇数时,结果值为 8n + 8,当 时,结果值为 8n + 16 >n 是偶数,从 s1 中减去该值得到 s2

令我困惑的是 8n + 22。为什么必须是 22,而不是 16, 17, 18, 19, 20, 21, 23

最佳答案

我现在看这里也有这个问题。

我尝试通过 clang 使用命令编译源代码:

clang -Og -S source.c -o source.s

在ubuntu18.04和windows 10这两个平台上,

程序集文件显示:

pushq   %rbp
movq %rsp, %rbp
subq $16, %rsp
movq %rsp, %r8
movq %rsp, %r9
leaq 15(,%rdi,8), %r10
andq $-16, %r10
movq %r9, %rax
...

clang 从 16 到 23 选择 15 甚至不是,

我读了The x86-64 psABI version 1.0 ,

3.2.2 堆栈框架部分:

The end of the input argument area shall be aligned on a 16 (32 or 64, if __m256 or __m512 is passed on stack) byte boundary. In other words, the value (%rsp + 8) is always a multiple of 16 (32 or 64) when control is transferred to the function entry point. The stack pointer, %rsp, always points to the end of the latest allocated stack frame.

所以我认为数字是 22 还是 15 并不重要,

数字刚好导致e1e2的大小

clang选择15,则当n为偶数时,e1e2 将小于 gcc 版本,

关键点是保护堆栈帧末尾的 16 字节对齐,

或可变大小堆栈帧中 s2 - s1 的值。

关于c - About Variable-Size Stack Frames,关于栈帧的对齐,来自CSAPP的一个例子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51592683/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com