了解这些装配说明

时间:2016-01-02 09:46:27

标签: c assembly cpu-registers

我通过编写C程序和查看程序集输出来学习汇编。我已经在页面底部包含了C程序,以便更轻松。我很难理解一条装配线:

cdqe

movzx eax,BYTE PTR [rbp-32 + rax]< ---这是做什么的?

movsx eax,al

所以我认为cdqe将eax扩展为rax(64位)。很明显,我想要打印的字符串符合al寄存器,但我不了解rbp-32 + rax内部正在发生的事情。有人可以帮我解释一下吗?

.file   "string_manip.c"
    .intel_syntax noprefix
    .section    .rodata
.LC0:
    .string "Hello"
    .string ""
    .zero   3
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    sub rsp, 48
    mov rax, QWORD PTR fs:40
    mov QWORD PTR [rbp-8], rax
    xor eax, eax
    mov DWORD PTR [rbp-36], 0
    mov eax, DWORD PTR .LC0[rip]
    mov DWORD PTR [rbp-32], eax
    movzx   eax, WORD PTR .LC0[rip+4]
    mov WORD PTR [rbp-28], ax
    movzx   eax, BYTE PTR .LC0[rip+6]
    mov BYTE PTR [rbp-26], al
    mov WORD PTR [rbp-25], 0
    mov BYTE PTR [rbp-23], 0
    mov DWORD PTR [rbp-36], 0
    jmp .L2
.L3:
    mov eax, DWORD PTR [rbp-36]
    cdqe
    movzx   eax, BYTE PTR [rbp-32+rax] <--- what is this doing?
    movsx   eax, al
    mov edi, eax
    call    putchar
    add DWORD PTR [rbp-36], 1
.L2:
    cmp DWORD PTR [rbp-36], 5
    jle .L3
    mov edi, 10
    call    putchar
    mov eax, 0
    mov rdx, QWORD PTR [rbp-8]
    xor rdx, QWORD PTR fs:40
    je  .L5
    call    __stack_chk_fail
.L5:
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4"
    .section    .note.GNU-stack,"",@progbits


#include <string.h>
#include <stdio.h>

int main()
{
    int i = 0;
    char array[10] = "Hello\0";
    for(i=0; i<6; i++)
        printf("%c", array[i]);
    printf("\n");
    return 0;
}

1 个答案:

答案 0 :(得分:2)

它只是计算其中一个字符的地址。

大概你的字符串从rbp-32开始,然后指令的C等价于ch = string[rax]

我想这是未经优化的代码,因此编译器会做一些额外的符号扩展和零扩展,这些都不是真正需要的。