[英]how to reverse-engineer the C integer type from the assembly code?
考虑以下C函数原型,其中num_t
是使用typedef声明的数据类型:
void store_prod(num_t *dest, unsigned x, num_t y) {
*dest = x*y;
}
gcc生成以下实现计算主体的汇编代码: num_t
是什么数据类型?
正确的答案是num_t
很unsigned long long
都没有unsigned long long
但我真的不明白为什么,任何帮助将不胜感激!
# dest at %ebp +8, x at %ebp +12, y at %ebp +16
movl 12(%ebp), %eax
movl 20(%ebp), %ecx
imull %eax, %ecx
mull 16(%ebp)
leal (%ecx,%edx), %edx
movl 8(%ebp), %ecx
movl %eax, (%ecx)
movl %edx, 4(%ecx)
从使用(%ebp)
寻址模式可以看出,这是32位代码,而不是x86-64。
在32位模式下, unsigned long long
是任何常见ABI中唯一的64位无符号整数类型。 (例如,在Linux上使用的i386 System V ABI)。 long
是32位。
我们可以说num_t
是64位整数类型,因为根据整数乘法和加法的结果,它存储在两个32位的一半中。
我们可以说这是一个unsigned
整数类型,因为gcc在x
和y
的imul
之间使用mul
而不是imul
。 (2-operand imul %eax, %ecx
将x
与y
的上半部分相乘的imul %eax, %ecx
是有符号或无符号的相同二进制运算:只有全数(N x N => 2N位)才关心符号性。)
IDK为什么gcc会使用leal (%ecx,%edx), %edx
而不是add %ecx, %edx
。 也许您使用-mtune=atom
编译? 不需要保留标志。
无论如何,这是一个普通的64 x 32 => 64位扩展精度乘法。
这是C,而不是C ++,因此也可以排除使用重载*
运算符包装64位整数的类。
我们可以排除FP类型,因为那会使用FP乘法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.