在x86汇编中遇到麻烦

时间:2016-02-24 06:21:29

标签: assembly x86

我在理解这个汇编代码的作用时遇到了一些麻烦。该函数接受一个整数参数,我应该弄清楚哪些参数允许我在这个块的末尾进行跳转。但是,我完全迷失在cmpsb正在做的事情上。我不知道%es%ds是什么或正在比较什么(参数和0x8048bb0作为字符串?)。

lea    0x1e(%esp),%edi    //loads the integer argument into edi register
mov    $0x8048bb0,%esi    //moves 0x8048bb0 into esi register
mov    $0xd,%ecx          //moves 13 into ecx register
repz cmpsb %es:(%edi),%ds:(%esi)  //a loop and a string byte comparison?
seta   %dl                //sets dl if previous comparison results in >
setb   %al                //sets al if previous comparison results in <
cmp    %al,%dl            //compares al and dl
je     8048851 <phase_3_of_5+0x69>  //jumps if al and dl are equal (meaning the above comparison was equal)

我已经尝试过搜索cmpsb的工作原理,但我找不到任何像这样的内容。

此外,setasetb有什么意义?如果它只是检查cmpsb是否相等,为什么je之后才会出现这种情况呢?

1 个答案:

答案 0 :(得分:1)

lea    0x1e(%esp),%edi    //loads a pointer to a string from stack to EDI
mov    $0x8048bb0,%esi    //loads a pointer to another string to ESI
mov    $0xd,%ecx          //moves 13 into ECX register
repz cmpsb %es:(%edi),%ds:(%esi)  //loops comparing values in ES:EDI and DS:ESI, continues until ECX is zero or a mismatching byte is found
seta   %dl                //sets DL if previous comparison results in >
setb   %al                //sets AL if previous comparison results in <
cmp    %al,%dl            //compares AL and DL
je     8048851 <phase_3_of_5+0x69>  //jumps if AL and DL are equal (meaning the above comparison was equal)

ESDS是段寄存器,:将段寄存器与偏移量分开。在16位世界中,它们很容易使用:地址DS:SI是DS * 16 + SI。在32/64位分段世界中,它们更复杂,它们是指向段表的指针,物理地址是从那里派生的。要理解的要点是,您总是需要一个段和一个偏移寄存器来指向任何东西。段寄存器可能在汇编代码中隐藏,但它始终存在。

段寄存器还表示即使ESI等于EDI,但您使用DS:ESIES:EDI,它们也可能指向不同的内存位置。当然,DS:ESIES:ESI可以指向不同的位置。

代码不比较字符串和整数。 ESIEDI都包含整数值,但它们用作指向内存位置的指针,并使用CMPSB命令将这些位置中的字节相互比较。 REPZ一直持续到比较不为零,或ECX变为零。

SETA / SETB指令非常无用,除非稍后使用它们的值。代码可以检查是否设置了零标志,这意味着所有比较都是相同的。因此ES:EDIDS:ESI指向的所有13个字节都是相等的。

代码不设置方向标志,因此不清楚要比较的字节是从ES:EDI开始还是向后。逻辑上的事情就是前进。