c - 将指针作为局部变量的函数的汇编指令

标签 c assembly stack gnu x86-64

我想了解如何为 c 生成程序集。我写了一个示例程序并对其进行了反汇编。

int main()
{
int a = 100;
}

程序集生成:

pushq   %rbp     #
movq    %rsp, %rbp   #,
subq    $48, %rsp    #,
call    __main   #
movl    $100, -4(%rbp)   #, a
leave
ret

这对我来说非常简单。但是当我在其中包含一个指针时,我不理解程序集。

C 程序:

int main()
{
int a = 100;
int *p = &a;
}

程序集生成:

pushq   %rbp     #
movq    %rsp, %rbp   #,
subq    $48, %rsp    #,
call    __main   #
movl    $100, -12(%rbp)  #, a
leaq    -12(%rbp), %rax  #, tmp59
movq    %rax, -8(%rbp)   # tmp59, p
leave
ret

我不明白为什么局部变量 a 现在被推到堆栈中与之前没有指针的片段相比的不同偏移量。

问题 #2: 如果我有 4 个局部变量,我的堆栈帧是 subq $48,%rsp,但是如果我将其中一个局部变量转换为指针,它是 subq $64。为什么会这样。

C 代码:

int main()
{
int a = 100;
int *p = &a;
int b = 10;
int c = 20;
}

程序集:

pushq   %rbp     #
movq    %rsp, %rbp   #,
subq    $64, %rsp    #,
call    __main   #
movl    $100, -20(%rbp)  #, a
leaq    -20(%rbp), %rax  #, tmp59
movq    %rax, -8(%rbp)   # tmp59, p
movl    $10, -12(%rbp)   #, b
movl    $20, -16(%rbp)   #, c
leave
ret

如果你们能解释为什么没有局部变量的主函数的堆栈帧是 2 * 16 字节对齐(32 字节),这也会很有帮助。猜想应该是为了一些簿记练习,但具体原因是什么?

谢谢,

最佳答案

编译器不会简单地将代码逐行从 c 语言转换为汇编语言。优化编译器将对代码进行大量分析,尝试执行诸如删除永远不会执行的代码、优化循环性能以及优化堆栈/内存使用等操作。当编译器决定在哪里分配内存和存储变量时,它知道 a 和 p,并将它们放在它认为最好的地方。

关于c - 将指针作为局部变量的函数的汇编指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16266248/

相关文章:

c - Makefile 中的 objs 破坏了内核模块

c - 签名右移 = 奇怪的结果?

assembly - 我的 memset 实现结果仅打印更改,而不是整个结果字符串

assembly - MIPS assembly 对齐 对齐 n

Java 收集程序显示错误 - 堆栈是抽象的,无法实例化

c - 尝试释放时出现堆错误

c - 对角带中的遍历矩阵

assembly - 最简单的链式加载引导管理器

D 中基于堆栈的对象实例化

algorithm - 铁路轨道的排列(堆栈实现)