在c中跳转未签名的指令

时间:2014-07-02 23:42:17

标签: c assembly x86

test ecx,ecx
jns 00400000

这个汇编代码是否等同于这个c代码?

int ECX;
if((ECX>>31)==1){..}

如果不能如何使它等效?

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

根据test instruction的Wikipedia条目,测试将根据寄存器ecx的最高位设置标志寄存器的符号标志。

因此,如果未设置MSB,则会跳转。您的补码C代码几乎相同,但根据>>是进行逻辑移位还是算术移位,您应该将其掩盖为安全。

if(((ECX>>31) & 1)==1){..}

当然,正如Jester所提到的,如果设置了有符号位,那么ECX < 0也是如此,因此在这种情况下这是一个更简单的测试。

答案 1 :(得分:0)

test reg,reg指令设置标志,这相当于在C中进行比较。因此,Jester提到reg < 0表示,是符号位设置。

但是,在C中你必须要小心你正在处理的变量类型。在您的情况下,您需要使用int32_t等类型。这样你就可以确保测试32位整数。 64位平台上的相同代码可能会将您的int转换为64位,并且符号会稍微提高一点。

当您在装配中进行测试时使用C中的移位实际上并不等效。实际上,如果你真的想使用移位,你应该使用无符号整数:

if((uint32_t)reg >> 31) { ... }

但实际上,这不是明智而且难以阅读的简单:

if(reg < 0) { ... }

不仅如此,它会更慢(2条指令而不是1条,虽然编译器可能会发现test reg,reg + jns就足够了,但你不应指望它。)