I'm having trouble understanding what the following lines of assembly do:
0x401810: repz cmps BYTE PTR ds:[rsi],BYTE PTR es:[rdi]
0x401812: seta dl
0x401815: setb al
I understand after debugging, the first instruction compares the bytes in registers rsi
and rdi
, byte by byte.
Then it sets the lower bytes of rdx
and rax
according based on that instruction.
My confusion is, when I looked up this instruction online, it said seta
sets the lower byte to 0x01 if its above a certain value, otherwise its 0x00. Similar for setb
, which sets the byte to 0x01 if its below a certain value.
My question is what value, and how is it related to the above instruction?
Subscripted SETA symbolsThe assembler assigns the value of the expression in the operand field to the position in the declared array given by the value of the subscript. The subscript expression must not be 0 or have a negative value.
The JB instruction branches to the address specified in the second operand if the value of the bit specified in the first operand is 1. The bit that is tested is not modified. No flags are affected by this instruction.
JBE, Jump if Below or Equal, should be used when comparing unsigned numbers. JLE, Jump if Less Than or Equal, should be used when comparing signed numbers.
It is used to produce object code for the x86 class of processors. Regarded as a programming language, assembly is machine-specific and low-level. Like all assembly languages, x86 assembly uses mnemonics to represent fundamental CPU instructions, or machine code.
The cmps
instruction compares [rsi]
and [rdi]
. The repz
prefix (alternately spelled repe
) means to increment rsi
and rdi
then repeat cmps
as long as [rsi]
and [rdi]
compare equal. The rflags
register will be set on each iteration; the final iteration where [rsi]
≠ [rdi]
is what will be used by seta
(set if above) and setb
(set if below).
In other words, the C pseudocode for those 3 instructions would look like this:
// 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
See the documentation for all of the setCC
instructions here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With