理解这些汇编指令

Understanding these assembly instructions

我正在通过编写 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[=10=]";
    for(i=0; i<6; i++)
        printf("%c", array[i]);
    printf("\n");
    return 0;
}

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

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

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