gpt4 book ai didi

c - 将无符号字符转换为有符号数据类型时,为什么在汇编中使用 movzbl?

转载 作者:行者123 更新时间:2023-12-04 14:17:47 26 4
gpt4 key购买 nike

我正在学习汇编中的数据移动( MOV )。
我尝试编译一些代码以在 x86_64 Ubuntu 18.04 机器中查看程序集:

typedef unsigned char src_t;
typedef xxx dst_t;

dst_t cast(src_t *sp, dst_t *dp) {
*dp = (dst_t)*sp;
return *dp;
}

哪里 src_tunsigned char .至于 dst_t , 我试过 char , short , intlong .
结果如下所示:
// typedef unsigned char src_t;
// typedef char dst_t;
// movzbl (%rdi), %eax
// movb %al, (%rsi)

// typedef unsigned char src_t;
// typedef short dst_t;
// movzbl (%rdi), %eax
// movw %ax, (%rsi)

// typedef unsigned char src_t;
// typedef int dst_t;
// movzbl (%rdi), %eax
// movl %eax, (%rsi)

// typedef unsigned char src_t;
// typedef long dst_t;
// movzbl (%rdi), %eax
// movq %rax, (%rsi)

我想知道为什么 movzbl在每种情况下都使用?不是应该对应 dst_t ?
谢谢!

最佳答案

如果您想知道为什么不movzbw (%rdi), %axshort ,那是因为写入 8 位和 16 位部分寄存器必须与之前的高字节合并。

写一个像 EAX 这样的 32 位寄存器隐式地将零扩展到完整的 RAX,避免对 RAX 的旧值或任何 ALU 合并 uop 的错误依赖。 ( Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register? )

在 x86 上加载字节的“正常”方式是使用 movzblmovsbl , 与 ARM 等 RISC 机器相同 ldrbldrsb , 或 MIPS lbu/lb .

GCC通常避免的奇怪的CISC事情是与仅替换低位的旧值合并,例如movb (%rdi), %al . Why doesn't GCC use partial registers? Clang 更加鲁莽,并且会更频繁地编写部分 regs,而不仅仅是为商店读取它们。您可能会看到 clang 加载到 %al和存储时间 dst_tsigned char .

如果您想知道为什么不movsbl (%rdi), %eax (符号扩展)

源值是无符号的,因此零扩展名 (不是符号扩展)是根据 C 语义扩展它的正确方法。获取movsbl ,你需要 return (int)(signed char)c .

*dp = (dst_t)*sp;投到dst_t从对 *dp 的赋值已经是隐含的.

unsigned char 的值范围是 0..255(在 x86 上,CHAR_BIT = 8)。

将此零扩展到 signed int可以产生一个值范围从 0..255 ,即将每个值保留为有符号的非负整数。

将此符号扩展到 signed int将产生一个值范围从 -128..+127 ,更改 unsigned char 的值values >= 128。这与 C 语义冲突,用于扩大转换保留值。

Shouldn't it correspond to dst_t?



它必须至少加宽为 dst_t .事实证明,使用 movzbl 扩展到 64 位(前 32 位由隐式零扩展写入 32 位 reg 处理)是最有效的加宽方式。

存储到 *dp是一个很好的演示,asm 适用于 dst_t宽度不是 32 位。

无论如何,请注意只有一次转换发生。您的 src_t转换为 dst_t在 al/ax/eax/rax 中使用加载指令,并存储到任何宽度的 dst_t 中。并且还留在那里作为返回值。

即使您只是要读取该结果的低字节,零扩展负载也是正常的。

关于c - 将无符号字符转换为有符号数据类型时,为什么在汇编中使用 movzbl?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58539038/

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