2016-10-27 47 views
0

当我觉得有时候我的代码将某个值视为signed并且有时在比较值时将其视为无符号时,我感到非常困惑。代码如何知道值是有符号还是无符号?汇编代码如何知道值是否已签名或未签名?

+2

如果你正在编写汇编代码,那么你有责任知道何时使用哪些指令。如果您使用某种其他语言进行编程,则根据您在代码中使用的数据类型,这将是编译器或解释器的职责。 – Michael

+0

除了明确签名或未签名的指令:它不知道。这是*你*谁写的代码谁知道。例如,比较会设置或清除各种标志,不知道您对该位模式的使用是有符号还是无符号的。您可以使用不同版本的分支指令,根据您的需要测试不同的标志组合。如果一条指令从结果的m.s.中设置符号标志。位,并且你的值是无符号的,那么你简单地忽略它。 –

+0

你能举个例子吗? – fuz

回答

1

如果您在C中声明了一个无符号的变量,它将被编译为带有无符号指令的汇编(通常执行起来更快) 如果您正在使用汇编,将会对一些处理器指令进行签名必须选择你真正需要的指示。

+0

大多数指令(例如add/sub)都不在意,它们都是相同的指令。也许你正在考虑MIPS,那里有ADD与ADDU,不同之处在于ADD在溢出(或类似的情况,IIRC)上触发了异常。正常签名与无签名仅适用于右移,除法和完全乘法(单词*单词 - >双字结果)。无论是有符号还是无符号,乘法的低半部分(即与输入操作数相同的宽度)是相同的。 (对于2的补充)。 –

+0

@rcgldr:我在评论中指出了所有这些情况。我想我的意思大多数是通过实际程序中的指令计数,而不是指令集中的大部分。但我的主要观点是很多指令都没有签名或未签名,它们只是指令。 **这个答案似乎意味着你总是需要不同的指令来签名和未签名,甚至为了加法,情况并非如此。** –

+0

@PeterCordes - 删除了我之前的评论,它是为其他文章而设,但是你已经覆盖了它。我稍后会删除此评论。 – rcgldr

3

为什么您认为汇编代码必须“知道”某个值是带符号还是无符号?

对于大多数操作的签署和usigned操作的结果是一样的:

signed int a = 5; 
signed int b = -6; // 0xFFFFFFFA 
signed int c; 
c = a + b; // results in -1 which is 0xFFFFFFFF 

和:

unsigned int a = 5; 
unsigned int b = 0xFFFFFFFA; 
unsigned int c; 
c = a + b; // results in 0xFFFFFFFF 

有些例外的是分工和比较。在这种情况下,大多数CPU对已签名和未签名的操作有不同的汇编指令。这里的例子是x86汇编,但MSP430应该是相似的:

signed int a, b; 
if(a > b) { ... } 

结果:

mov eax, [a] 
cmp eax, [b] 
jle elsePart ; Note the "L" in "jle" 

和:

mov eax, [a] 
cmp eax, [b] 
jbe elsePart ; Note the "B" in "jbe" 
2

机器:在

unsigned int a, b; 
if(a > b) { ... } 

结果不关心或不知道什么是签名或你除非你是这么说的,否则请签署。

在汇编程序开发人员居住的层面上,机器是砖块,你是导体。您必须足够了解该机器的指令集的合同以及诸如flags之类的内容才能确保确定性结果。

相关问题