简体   繁体   English

在Linux上将C程序转换为Assembly(x86_64)

[英]C Program translation to Assembly (x86_64) on Linux

I'm a newbie to assembly programming (especially x86_64).I have translated the following c program to assembly. 我是汇编程序设计的新手(尤其是x86_64)。我已将以下c程序翻译为汇编程序。

I understood most of the code but I'm not able to interpret the 2 Instructions I've commented out . 我理解了大多数代码,但是无法解释我注释掉的2条指令。

* Isn't the stmnt 1 corrupting contents of rax register by copying 42 to its lower word ? * stmnt 1是不是通过将42复制到低位字来破坏rax寄存器的内容?


note: as per the logic stmnt 1 should increment 42 in location whose address is stored in rax 注意:按照逻辑stmnt 1应该在其地址存储在rax中的位置增加42

addl $1,(%rax) 

could some one explain those 2 instructions . 有人可以解释这2条指令吗?


temp.c temp.c

    #include<stdio.h>

    int main()
    {
        int a=42,*ptr;

        ptr = &a;
        (*ptr)++;

        return 0;
    }

temp.s temp.s

        .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

Yes, stmt1 is overwriting rax , but that is not a problem. 是的, stmt1正在覆盖rax ,但这不是问题。 stmt2 is then doing edx = eax + 1 in a tricky way using lea . 然后, stmt2使用lea以棘手的方式执行edx = eax + 1 The incremented value in edx is written back into memory at movl %edx, (%rax) . edx的递增值以movl %edx, (%rax)写回到内存中。 This means the (*ptr)++; 这意味着(*ptr)++; has been split into multiple steps like this: 已分为多个步骤,如下所示:

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 */

Yes, addl $1,(%rax) could have been used. 是的,可能已经使用了addl $1,(%rax) You probably don't have optimization enabled which is why you see inefficient code. 您可能没有启用优化,这就是为什么看到无效代码的原因。

With optimization enabled, the following code: 启用优化后,以下代码:

void foo(int* ptr)
{
    (*ptr)++;
}

produces this assembly: 产生这个程序集:

    addl    $1, (%rdi)
    ret

And this: 和这个:

void foo(int* ptr)
{
    *ptr = 42;
    (*ptr)++;
}

gives: 得到:

    movl    $43, (%rdi)
    ret

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM