G'evening. I'm doing a lab work on Assembly. I have to compare 3 numbers -8, -2 and 11 to get the greatest. I translated them in an additional code and represented them in hexadecimal notation. So I get wrong answer because -2 = FE > 11 = B. The question is how can I compare these numbers correctly? I use nasm, x86.
CodePudding user response:
The compare instruction, as well as almost every arithmetic instructions will modify a set of flags in a status register.
The flags are modified independent of the intent of an instruction -- e.g. the Parity Flag or Auxiliary Flag is modified regardless of the (rare) need to check the status of that flag.
When -2 is compared with 11, or 11 is subtracted from -2, the processor actually does not know that -2 is negative; instead 0xfe - 0x0b is computed, which does not overflow, thus CarryFlag == 0. Also because the result is not zero, ZeroFlag == 0 as well. And because 0xFE has a different sign than 0x0b, OverflowFlag == 0 too.
The different combinations of all these OF,ZF,CF map to higher level abstractions, such as unsigned <= unsigned
, any != any
, signed > signed
. In Intel Architecture 'Below / Above' refer to unsigned compares and 'Greater / Less' refer to signed comparison -- also the same set of flags can refer to multiple abstractions, such as JC
(see http://unixwiz.net/techtips/x86-jumps.html)
The subset of signed comparisons you probably need are then either JG
or it's complement JNG
, which stands for Jump Not Greater, which is equal to JLE
or Jump Less or Equal.
In addition to conditional branch, x64 instruction set supports conditional set/move of a register and armv7 allows conditional execution of most instructions and armv8 allows conditional execution of some interesting sequences of instructions (like a = b iff LessThan, else a = c 1
).