gpt4 book ai didi

c++ - 编译器在这里生成的汇编代码中的寻址模式是什么?

转载 作者:行者123 更新时间:2023-11-27 22:30:17 25 4
gpt4 key购买 nike

假设我们有两个整数和字符变量:

int adad=12345;
char character;

假设我们正在讨论一个平台,其中整数变量的长度大于或等于三个字节,我想访问该整数的第三个字节并将其放入字符变量中,也就是说我会像这样写:

character=*((char *)(&adad)+2);

考虑到那行代码以及我不是编译器或汇编专家的事实,我对汇编中的寻址模式了解一些,我想知道第三个字节的地址 (或者我想最好说第三个字节的偏移量) 会在该行代码本身生成的指令中,或者在一个单独的变量中,该变量的地址(或 offset)在这些说明中?

最佳答案

在这种情况下最好的办法就是尝试一下。这是一个示例程序:

int main(int argc, char **argv)
{
int adad=12345;
volatile char character;

character=*((char *)(&adad)+2);

return 0;
}

我添加了 volatile 以避免分配行被完全优化掉。现在,这是编译器的结果(对于我的 Mac 上的 -Oz):

_main:
pushq %rbp
movq %rsp,%rbp
movl $0x00003039,0xf8(%rbp)
movb 0xfa(%rbp),%al
movb %al,0xff(%rbp)
xorl %eax,%eax
leave
ret

我们唯一关心的三行是:

    movl    $0x00003039,0xf8(%rbp)
movb 0xfa(%rbp),%al
movb %al,0xff(%rbp)

movladad的初始化。然后,如您所见,它读出 adad 的第 3 个字节,并将其存储回内存(volatile 强制存储回内存)。

我想一个很好的问题是,为什么生成什么程序集对您很重要?例如,只需将我的优化标志更改为 -O0,代码中有趣部分的汇编输出就是:

    movl    $0x00003039,0xf8(%rbp)
leaq 0xf8(%rbp),%rax
addq $0x02,%rax
movzbl (%rax),%eax
movb %al,0xff(%rbp)

这可以很直接地视为代码的确切逻辑操作:

  1. 初始化adad
  2. adad的地址
  3. 将 2 添加到该地址
  4. 通过取消引用新地址加载一个字节
  5. 将一个字节存入字符

各种优化会改变输出...如果您出于某种原因确实需要某些特定的行为/寻址模式,您可能必须自己编写程序集。

关于c++ - 编译器在这里生成的汇编代码中的寻址模式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3430848/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com