[英]C Program translation to Assembly (x86_64) on Linux
我是匯編程序設計的新手(尤其是x86_64)。我已將以下c程序翻譯為匯編程序。
我理解了大多數代碼,但是無法解釋我注釋掉的2條指令。
* stmnt 1是不是通過將42復制到低位字來破壞rax寄存器的內容?
注意:按照邏輯stmnt 1應該在其地址存儲在rax中的位置增加42
addl $1,(%rax)
有人可以解釋這2條指令嗎?
#include<stdio.h>
int main()
{
int a=42,*ptr;
ptr = &a;
(*ptr)++;
return 0;
}
.file "temp.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
movl $42, -20(%rbp)
leaq -20(%rbp), %rax
movq %rax, -16(%rbp)
movq -16(%rbp), %rax
movl (%rax), %eax ; stmt 1
leal 1(%rax), %edx ; stmt 2
movq -16(%rbp), %rax
movl %edx, (%rax)
movl $0, %eax
movq -8(%rbp), %rcx
xorq %fs:40, %rcx
je .L3
call __stack_chk_fail
.L3:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413"
.section .note.GNU-stack,"",@progbits
是的, stmt1
正在覆蓋rax
,但這不是問題。 然后, stmt2
使用lea
以棘手的方式執行edx = eax + 1
。 edx
的遞增值以movl %edx, (%rax)
寫回到內存中。 這意味着(*ptr)++;
已分為多個步驟,如下所示:
rax = ptr; /* load pointer */
eax = *rax; /* fetch current value */
edx = eax + 1; /* calculate new value */
rax = ptr; /* load pointer again */
*rax = edx; /* write new value */
是的,可能已經使用了addl $1,(%rax)
。 您可能沒有啟用優化,這就是為什么看到無效代碼的原因。
啟用優化后,以下代碼:
void foo(int* ptr)
{
(*ptr)++;
}
產生這個程序集:
addl $1, (%rdi)
ret
和這個:
void foo(int* ptr)
{
*ptr = 42;
(*ptr)++;
}
得到:
movl $43, (%rdi)
ret
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.