我不明白为什么 gcc -S -m32
会产生这些特定的代码行:
movl %eax, 28(%esp)
movl $desc, 4(%esp)
movl 28(%esp), %eax
movl %eax, (%esp)
call sort_gen_asm
我的问题是为什么 %eax
被压入然后弹出?为什么分别使用 movl
而不是 pushl
和 popl
?它更快吗?是否有一些我还不知道的编码约定?我刚刚开始仔细研究 asm-output,所以我了解的不多。
C 代码:
void print_array(int *data, size_t sz);
void sort_gen_asm(array_t*, comparer_t);
int main(int argc, char *argv[]) {
FILE *file;
array_t *array;
file = fopen("test", "rb");
if (file == NULL) {
err(EXIT_FAILURE, NULL);
}
array = array_get(file);
sort_gen_asm(array, desc);
print_array(array->data, array->sz);
array_destroy(array);
fclose(file);
return 0;
}
它给出了这个输出:
.file "main.c"
.section .rodata
.LC0:
.string "rb"
.LC1:
.string "test"
.text
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $32, %esp
movl $.LC0, 4(%esp)
movl $.LC1, (%esp)
call fopen
movl %eax, 24(%esp)
cmpl $0, 24(%esp)
jne .L2
movl $0, 4(%esp)
movl $1, (%esp)
call err
.L2:
movl 24(%esp), %eax
movl %eax, (%esp)
call array_get
movl %eax, 28(%esp)
movl $desc, 4(%esp)
movl 28(%esp), %eax
movl %eax, (%esp)
call sort_gen_asm
movl 28(%esp), %eax
movl 4(%eax), %edx
movl 28(%esp), %eax
movl (%eax), %eax
movl %edx, 4(%esp)
movl %eax, (%esp)
call print_array
movl 28(%esp), %eax
movl %eax, (%esp)
call array_destroy
movl 24(%esp), %eax
movl %eax, (%esp)
call fclose
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.8.1-10ubuntu8) 4.8.1"
.section .note.GNU-stack,"",@progbits
最佳答案
eax
的保存/加载是因为您没有进行优化编译。因此,对变量的任何读/写都会发出内存地址的读/写。
实际上,对于(几乎)任何一行代码,您都能够识别出由它产生的确切的汇编代码片段(我建议您使用 gcc -g -c -O0
进行编译然后 objdump -S file.o
):
#array = array_get(file);
call array_get
movl %eax, 28(%esp) #write array
#sort_gen_asm(array, desc);
movl 28(%esp), %eax #read array
movl %eax, (%esp)
...
关于不推送/弹出,是标准的零成本优化。每次你想调用一个函数时,你都不需要推送/弹出,你只需在函数的开头减去最大需要的空间到 esp
,然后将你的函数参数保存在空白空间的底部。有很多优点:更快的代码(无需更改 esp
),不需要以任何特定顺序计算参数,并且 esp
需要无论如何减去局部变量空间。
关于c - 为什么 GCC 会产生以下 asm 输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19835076/