当我看到用C/C++编写的代码的反汇编时,我总是觉得这很令人困惑.
有一个有一定价值的寄存器.我想知道它是代表签名号码还是无符号号码.我怎么能找到这个?
我的理解是,如果它是有符号整数,如果它是负数,则将设置MSB,如果它是正数则不设置.如果我发现它是无符号整数,则MSB无关紧要.它是否正确?
无论如何,这似乎没有帮助:在我可以使用此信息之前,我仍然需要确定整数是否已签名.如何才能做到这一点?
您最好的选择是寻找比较和相关的操作/标记用法,如分支.根据类型,编译器将生成不同的代码.由于大多数(相关)体系结构提供了处理签名值的标志.以x86为例:
jg, jge, jl, jle = branch based on a signed comparison (They check for the SF flag)
ja, jae, jb, jbe = branch based on a unsigned comparison (They check for the CF flag)
Run Code Online (Sandbox Code Playgroud)
对于签名/未签名操作,CPU上的大多数指令都是相同的,因为我们现在使用的是Two's-Complement表示.但也有例外.
让我们以右移为例.使用X86上的无符号值,您可以使用SHR将某些内容向右移动.这将在左侧的每个"新创建的位"上添加零.
但是对于有符号值,通常会使用SAR,因为它会将MSB扩展到所有新位.多数民众赞成称"符号扩展",并且只能使用,因为我们正在使用Two's-Complement.
最后但并非最不重要的是,对签名/无符号乘法/除法有不同的指令.
imul+idiv = signed
mul+div = unsigned
Run Code Online (Sandbox Code Playgroud)
正如评论中所指出的,imul是一种特殊情况,因为它也可以用于无符号乘法.唯一的区别在于正在设置的标志.因此,如果您看到imul值,请不要太信任代码,这取决于具体情况.
NEG指令通常也只用于有符号值,因为它是一个二进制补码否定.
一般来说,你将无法做到。整数值发生的许多事情与有符号或无符号值发生的情况相同。例如,作业。唯一的判断方法是代码是否恰好在进行算术运算。你绝对不能通过看价值来判断;无论哪种方式,所有可能的位模式都是有效的。
| 归档时间: |
|
| 查看次数: |
11085 次 |
| 最近记录: |