理解指针和汇编中的铸造

understanding pointers and casting in assembly

我在汇编中得到了一个函数,它基本上将大写字母转换为小写字母。这是一些程序集,

 Q1:
    pushq %rbp
    movq %rsp, %rbp 
    subq , %rsp
    movq %rdi, -24(%rbp)
    movl [=10=], -4(%rbp)
    movl [=10=]. -8%(%rbp) 
    jmp .L2
L2:
    movl -4(%rbp) %edx
    movq -24(%rbp), %rax
    addq %rdx, %rax
    movzbl (%rax), %eax
    testb %al, %al
    jne .L4
    ...

其余大部分都是重复的,但 L2 才是真正让我困惑的地方。到目前为止,这是我的逻辑: 我们将 param1 存储到 -24(%rbp)。我们创建 local1 和 local2,将它们都设置为 0,然后跳转到 L2。我将 local1 移动到 %edx,将 param1 移动到 %rax。现在这就是让我感到困惑的地方, 我被告知以下行,addq 最终在 local1 中成为指向 param1 的指针。我只是推理添加 local1 + param1 并将它们存储到 %rax 中。这怎么可能?

接下来是movzbl。根据我的理解,我们取消引用 %rax 所以我们得到类似 eax = (int) rax 的东西。

我还被告知将其视为将 char 转换为 int。哪一个是真的,我怎么知道我在打字?如果 %rax 没有括号呢?它是一个 int 吗,因为它是 4 个字节,而 %eax 是一个 32 位寄存器。预先感谢您的帮助,我有点迷路了....

local1 不是一个指针,它是一个索引(一个计数器)。 该代码正在做类似的事情:

void toupper(char* text)
{
    int i = 0;  /* at rbp-4 */
    int j = 0;  /* unused, at rbp-8 */
    int ch;     /* in eax */
    while((ch = *(text + i)) != 0)
    {
        ...
    }
}

请注意,在 C 指针运算中 *(text + i) 当然等同于 text[i]

是的,movzbl 正在将 unsigned char 转换为 int 您可以从指令名称本身看到:MOVe Zero 将 Byte 扩展到 Long。

括号表示指针取消引用。