c - 理解指针和汇编中的类型转换

标签 c assembly x86-64

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

 Q1:
    pushq %rbp
    movq %rsp, %rbp 
    subq $24, %rsp
    movq %rdi, -24(%rbp)
    movl $0, -4(%rbp)
    movl $0. -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 您可以从指令名称本身看到:MOV e Zero 将Byte 扩展为Long。

括号表示指针取消引用。

关于c - 理解指针和汇编中的类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33770585/

相关文章:

将汇编内联从 32 位转换为 64 位

assembly - Visual Studio C++ 的函数序言

linux - NASM:如何使用英特尔 64 位程序集创建/处理基本 bmp 文件?

c - 指向 ANSI C 中定义的空指针的指针吗?

C:malloc()、free() 和 malloc() 是否总是一样工作?

android - 在没有内存访问的线路上发出 SIGBUS 信号

c - 为什么在 MSP430-GCC 中优先使用 int 而不是 (unsigned) char 作为小整数

汇编语言 : 8 bit versions of 64 bit registers?

c - 为什么我们可以读取这个分配的指针中的任何字符而不写入它?

c - 在 C Caesar Cipher 中使用 ASCII 解密具有未知 key 的打开的文本文件