【发布时间】:2015-01-27 16:00:44
【问题描述】:
我正在用x86 asm 做几个实验,试图了解通用语言构造如何映射到汇编中。在我目前的实验中,我试图具体了解 C 语言指针如何映射到寄存器间接寻址。我已经写了一个类似 hello-world 的指针程序:
#include <stdio.h>
int
main (void)
{
int value = 5;
int *int_val = &value;
printf ("The value we have is %d\n", *int_val);
return 0;
}
并使用:gcc -o pointer.s -fno-asynchronous-unwind-tables pointer.c:[1][2]
.file "pointer.c"
.section .rodata
.LC0:
.string "The value we have is %d\n"
.text
.globl main
.type main, @function
main:
;------- function prologue
pushq %rbp
movq %rsp, %rbp
;---------------------------------
subq $32, %rsp
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
;----------------------------------
movl $5, -20(%rbp) ; This is where the value 5 is stored in `value` (automatic allocation)
;----------------------------------
leaq -20(%rbp), %rax ;; (GUESS) If I have understood correctly, this is where the address of `value` is
;; extracted, and stored into %rax
;----------------------------------
movq %rax, -16(%rbp) ;;
movq -16(%rbp), %rax ;; Why do I have two times the same instructions, with reversed operands???
;----------------------------------
movl (%rax), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
;----------------------------------
movl $0, %eax
movq -8(%rbp), %rdx
xorq %fs:40, %rdx
je .L3
call __stack_chk_fail
.L3:
leave
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.9.1-16ubuntu6) 4.9.1"
.section .note.GNU-stack,"",@progbits
我的问题是我不明白为什么它包含指令movq 两次,操作数相反。有人可以向我解释一下吗?
[1]:当我根本不需要 cfi 指令时,我想避免在我的 asm 代码中穿插它们。
[2]:我的环境是Ubuntu 14.10、gcc 4.9.1(由ubuntu修改)和Gnu assembler (GNU Binutils for Ubuntu) 2.24.90.20141014,配置为目标x86_64-linux-gnu
【问题讨论】:
-
如果你不告诉 gcc 进行优化,它会产生 非常 愚蠢的代码。如您所见,它将所有局部变量存储在堆栈中,即使它可以很容易地保存在寄存器中。要获得合理的代码,请告诉 gcc 使用
-O3进行优化。 -
我只能回应 EOF 的评论。我发现
-O对我来说是最易读的:-O3可以应用阻碍程序集中源代码可追溯性的转换。出于与您使用-fno-asynchronous-unwind-tables相同的原因,您可能也喜欢-fomit-frame-pointer(对于简单的功能,生成的程序集实际上更轻且更易于理解)。除非您有时间浪费,否则不要阅读使用-O0生成的代码。 -
@EOF 是的,我已经看到它对
-O3的作用,虽然它更干净,但它优化了我的指针(以及更多),这样我就失去了我的想看看原创:指针如何映射到寄存器间接寻址。 -
如果不想优化变量,也可以使用
-Og
标签: c linux gcc assembly x86-64