Assembly x86程序集中的符号冲突:movsx然后是无符号比较/分支?

Assembly x86程序集中的符号冲突:movsx然后是无符号比较/分支?,assembly,x86,masm,micro-optimization,signedness,Assembly,X86,Masm,Micro Optimization,Signedness,我对以下片段感到困惑: movsx ecx, [ebp+var_8] ; signed move cmp ecx, [ebp+arg_0] jnb short loc_401027 ; unsigned jump 这似乎有冲突。Var_8似乎是由于其得到符号扩展而被签名的。然而,jnb暗示var_8没有在帐户上签名,它是一个未签名的比较 那么,var_8是有符号的还是无符号的?那么arg_0呢?正如Jester所指出的,无符号比较可以用于对有符号数字进行范围检查。例如,检查

我对以下片段感到困惑:

movsx   ecx, [ebp+var_8] ; signed move
cmp     ecx, [ebp+arg_0]
jnb     short loc_401027 ; unsigned jump
这似乎有冲突。Var_8似乎是由于其得到符号扩展而被签名的。然而,jnb暗示var_8没有在帐户上签名,它是一个未签名的比较


那么,var_8是有符号的还是无符号的?那么arg_0呢?

正如Jester所指出的,无符号比较可以用于对有符号数字进行范围检查。例如,检查索引是否介于0和某个限制之间的常用C表达式:

short idx = ...;
int limit = ...; // actually, it's called "arg_0" - is it a function's argument?
if (idx >= 0 && idx < limit)
{
    // do stuff
}

安纳托利答复附录:

原则上,在装配级别上没有冲突

计算机中的信息是以位编码的(一位=零或一),而ecx是32位的信息,没有别的

无论您是否将顶部位解释为符号,这取决于以下代码,即在汇编级别,使用
movsx
扩展值(以类似符号的方式)是完全合法的,即使您稍后将其解释为位掩码或无符号整数

逻辑层是否存在冲突取决于作者计划的功能。如果作者确实希望针对
arg_0
的测试在
var_8
为“负值”且
arg_0
<231时不分支,则代码是正确的

顺便说一句,反汇编在第一个
movsx
中缺少关于参数大小的信息,因此产生这种情况的反汇编工具令人困惑(否则好吗?请小心)

那么,var_8是有符号的还是无符号的?那么arg_0呢

var_8
是第一个也是最重要的内存地址,从中可以使用8位或16位信息(反汇编中不清楚是哪一位),以“有符号”的方式使用。但是如果不研究完整的代码,就很难进一步了解
var_8
,甚至可能
var_8
是32位无符号int“变量”,但出于某种原因,作者决定在第一个
movsx
中只使用扩展的低16位内容
arg_0
然后用作
cmp
指令的无符号32位整数

在汇编中,问题不在于
var_8
是有符号的还是无符号的,而在于汇编中的问题是您有多少位信息,在哪里,以及以下代码对这些位的解释是什么

这比C或其他高级编程语言有更多的自由度,例如,如果内存中有四个字节的计数器,您知道每个计数器都小于200,并且您想增加第一个和最后一个计数器,您可以这样做:

.data
counter1: db 13
counter2: db 6
counter3: db 34
counter4: db 17

.text
    ...
    ; increment first and last counter in one instruction
    ; overflow not-expected/handled, counters should to be < 200
    add  dword [counter1],0x01000001
.data
计数器1:db 13
计数器2:db 6
计数器3:db 34
计数器4:db 17
.文本
...
; 在一条指令中递增第一个和最后一个计数器
; 未预期/处理溢出,计数器应<200
添加dword[counter1],0x01000001

现在(想象一下)在没有来自上述源代码的原始注释的情况下,在反汇编此类代码时,您将如何解释这一点?如果您不理解另一个代码中的
计数器1-4
被用作单独的字节计数器,这是一个速度优化,可以在一条指令中增加两个计数器。

这可能是这样的范围检查的结果,下限不仅限于0,还限于任何整数值

int8_t var_8=。。。;

使用无符号比较的if(LOWER_BOUND)是以
0的形式进行范围检查的常见技巧
.data
counter1: db 13
counter2: db 6
counter3: db 34
counter4: db 17

.text
    ...
    ; increment first and last counter in one instruction
    ; overflow not-expected/handled, counters should to be < 200
    add  dword [counter1],0x01000001