Hom*_*512 8 c assembly x86-64 micro-optimization
我想替换整数中的最低字节。在 x86 上这确实是这样mov al, [mem],但我似乎无法让编译器输出它。我是否遗漏了一个明显的可识别代码模式,我是否误解了某些内容,或者这只是一个错过的优化?
unsigned insert_1(const unsigned* a, const unsigned char* b)
{
return (*a & ~255) | *b;
}
unsigned insert_2(const unsigned* a, const unsigned char* b)
{
return *a >> 8 << 8 | *b;
}
Run Code Online (Sandbox Code Playgroud)
GCC 实际上使用al但只是为了归零。
mov eax, DWORD PTR [rdi]
movzx edx, BYTE PTR [rsi]
xor al, al
or eax, edx
ret
Run Code Online (Sandbox Code Playgroud)
Clang 几乎逐字编译两者
mov ecx, -256
and ecx, dword ptr [rdi]
movzx eax, byte ptr [rsi]
or eax, ecx
ret
Run Code Online (Sandbox Code Playgroud)
在 x86 上这确实是这样
mov al, [mem],但我似乎无法让编译器输出它。
试试这个,无需算术:
unsigned insert_4(const unsigned* a, const unsigned char* b)
{
unsigned int t = *a;
unsigned char *tcp = (unsigned char *) & t;
tcp[0] = *b;
return t;
}
Run Code Online (Sandbox Code Playgroud)
insert_4(unsigned int const*, unsigned char const*):
mov eax, DWORD PTR [rdi]
mov al, BYTE PTR [rsi]
ret
Run Code Online (Sandbox Code Playgroud)
我知道有点奇怪,但编译器擅长删除局部变量的间接寻址和地址(尽管尝试了几次......)。
使用 union 的替代方案:
unsigned insert_5(const unsigned* a, const unsigned char* b)
{
union {
unsigned int ui;
unsigned char uc;
} u;
u.ui = *a;
u.uc = *b;
return u.ui;
}
Run Code Online (Sandbox Code Playgroud)
请注意,这些解决方案是特定于字节序的,尽管它看起来像您正在寻找的,并且可以根据需要针对其他字节序进行调整。
| 归档时间: |
|
| 查看次数: |
202 次 |
| 最近记录: |