在repz cmpsb之后,汇编指令'seta'和'setb'做了什么?

时间:2017-06-19 12:11:52

标签: assembly x86 x86-64

我无法理解以下装配线的作用:

0x401810:    repz cmps BYTE PTR ds:[rsi],BYTE PTR es:[rdi]
0x401812:    seta   dl
0x401815:    setb   al

我理解调试后,第一条指令逐字节地比较寄存器rsirdi中的字节。

然后根据该指令设置rdxrax的低位字节。

我的困惑是,当我在线查看此指令时,它说seta如果高于某个值,则将低位字节设置为0x01,否则将其设置为0x00。类似于setb,如果字节低于某个值,则将字节设置为0x01。

我的问题是什么价值,它与上述指令有什么关系?

2 个答案:

答案 0 :(得分:9)

cmps instruction比较[rsi][rdi]repz prefix(交替拼写为repe)表示增加rsirdi,然后重复cmps,只要[rsi][rdi]比较平等。每次迭代都会设置rflags寄存器; [rsi][rdi]的最后一次迭代是seta(如果在上面设置)和setb(如果在下面设置)将使用的。

换句话说,这3条指令的C伪代码如下所示:

// Initial values
uint8_t *rsi = (...);
uint8_t *rdi = (...);
uint64_t rcx = (...);

// repz cmps BYTE PTR [rsi], BYTE PTR [rdi]
while (*rsi == *rdi && rcx > 0) {
    rsi++;
    rdi++;
    rcx--;
}

uint8_t dl = *rsi > *rdi;   // seta dl
uint8_t al = *rsi < *rdi;   // setb al

请参阅所有setCC说明here的文档。

答案 1 :(得分:5)

指令助记符是:

  • repz cmps ds:[esi], es:[edi]
    比较字符串,而字符串比较相等
  • seta dl
    如果设置了上述标志,则将dl设置为1;如果不是
  • ,则将dl设置为0
  • setb al
    如果设置了以下标志,则将al设置为1,如果不是
  • ,则设置为0

除了检查零标志外,repz还使用ecx寄存器指定最大重复次数。 (ecx也称为计数器寄存器。)

正如下面Jester正确指出的

[EDIT],没有上面和下面的标志,上面和下面是cpu状态标志位操作的结果:

  • 以上:CF = 0且ZF = 0
  • 如下:CF = 1