识别程序集中的有符号和无符号值

use*_*594 11 assembly

当我看到用C/C++编写的代码的反汇编时,我总是觉得这很令人困惑.

有一个有一定价值的寄存器.我想知道它是代表签名号码还是无符号号码.我怎么能找到这个?

我的理解是,如果它是有符号整数,如果它是负数,则将设置MSB,如果它是正数则不设置.如果我发现它是无符号整数,则MSB无关紧要.它是否正确?

无论如何,这似乎没有帮助:在我可以使用此信息之前,我仍然需要确定整数是否已签名.如何才能做到这一点?

Nic*_*rth 7

您最好的选择是寻找比较和相关的操作/标记用法,如分支.根据类型,编译器将生成不同的代码.由于大多数(相关)体系结构提供了处理签名值的标志.以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指令通常也只用于有符号值,因为它是一个二进制补码否定.

  • `imul`(2+操作数版本)也可能是无符号的。并且“je”(又名“jz”)对于无符号比较(甚至是非比较)完全有效。 (3认同)

bma*_*ies 5

一般来说,你将无法做到。整数值发生的许多事情与有符号或无符号值发生的情况相同。例如,作业。唯一的判断方法是代码是否恰好在进行算术运算。你绝对不能通过看价值来判断;无论哪种方式,所有可能的位模式都是有效的。