12

你好,我需要一些帮助来理解这个汇编代码中发生了什么:

        .file   "mystery.c"

        .text

        .globl mystery

              .type mystery, @function

 mystery:
   pushq    %rbp
    movq    %rsp, %rbp

   movl %edi, -20(%rbp)
   movl $1, -16(%rbp)
   movl $0, -12(%rbp)
   movl $0, -8(%rbp)
   cmpl $2, -20(%rbp)
   jg   .L2
   movl $1, %eax
   jmp  .L3

  .L2:
movl    $2, -4(%rbp)
jmp .L4

  .L5:
movl    -12(%rbp), %eax
movl    -16(%rbp), %edx
leal    (%rdx,%rax), %eax
movl    %eax, -8(%rbp)
movl    -16(%rbp), %eax
movl    %eax, -12(%rbp)
movl    -8(%rbp), %eax
movl    %eax, -16(%rbp)
addl    $1, -4(%rbp)

.L4:
movl    -4(%rbp), %eax
cmpl    -20(%rbp), %eax
jle .L5
movl    -8(%rbp), %eax

.L3:
leave
ret

我完全理解发生了什么,直到我到达 .L5,这里的命令leal(%rdx, %rax), eax 让我感到困惑。到目前为止,我一直在将值移动到 eax 和 edx,现在我将值添加到 rdx 和 rax 中。rdx 和 rax 来自哪里,他们持有什么价值观?它们只是写 eax 和 edx 的另一种方式吗?谢谢你的帮助。

4

3 回答 3

20

请参阅相关答案。它解释了不同的寄存器及其演变。在这种情况下,该%rax寄存器是一个 64 位寄存器。%eax是 32 位的,%ax将是 16 位。%ah指寄存器16位中的高8位,%al指低端。

这个小图表取自同一问题的另一个答案,但它很好地展示了它......

|63..32|31..16|15-8|7-0|
               |AH.|AL.|
               |AX.....|
       |EAX............|
|RAX...................|
于 2012-10-29T18:38:05.673 回答
7

这些是描述寄存器的“真的只是”其他方式。根据“前缀”,它们是 64、32、16 或 8 位:

  • rax- 64 位
  • eax- 32 位
  • ax- 16 位
  • ah- 高 8 位ax
  • al- 低 8 位ax
于 2012-10-29T18:36:50.897 回答
3

因为在 64 位模式下,lea使用 64 位“地址”和 32 位目标是最短的编码。

使其成为 32 位地址不会影响结果,但会花费一个字节。

于 2012-10-29T18:37:05.940 回答