0

The assembler has this code:

sub$0x22,%eax # %eax = %eax - 22
cmp$0x7,%eax  # %eax > 7 then jump *this is where I have trouble*
ja some address # jump if C = 1 or Z = 1

My goal is to not make the jump. I have tried the cases where %eax = 30, 14, 28, 16, 0 , 22

Question: I don't understand why c=0 and z=0 with all the cases I have tried.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Nandar Soe
  • 35
  • 1
  • 5
  • 1
    Are those sample eax values hex or decimal? – Josiah Keller Sep 11 '18 at 00:45
  • 1
    `ja` will jump when CF **and** ZF are 0, not "if C = 1 or Z = 1". And the first line does subtract 0x22 (hexadecimal) = 34 in decimal, so your test values were in what formatting? 28 or 0x28? With 0x28 (40 decimal) -> eax = 6 (0x28 - 0x22), `cmp $7,%eax` will set CF=1,ZF=0, and the jump will be ignored. – Ped7g Sep 11 '18 at 06:12
  • Maybe add description of ranges for input values, when you expect jump, and when not, so one can show you correct code for that, your current code will NOT jump to "some address" for eax values from range 0x22 (34) .. 0x29 (41). Everything else will jump. The code looks like common idiomatic way how to limit eax to certain range of values and normalize it against it's minimal value, i.e. often used to check if value is ASCII digit (would check for range 0x30..0x39 and use thus `sub $0x30,%eax` `cmp $0x9,%eax` `ja not_ascii_digit` and here `eax` contains value 0..9 depending on input char) – Ped7g Sep 11 '18 at 06:19
  • Thank you for the clarification! – Nandar Soe Sep 11 '18 at 23:21

1 Answers1

1

0x22, which is 34 decimal, is larger than all of those sample eax values (assuming they're decimal). Thus, the result of the subtraction is negative. But a "negative" integer is just an integer where the most significant bit is a 1, and can also be interpreted as a large unsigned number.

It's probably easier to think of ja in terms of what it means conceptually rather than the actual logic on the flags. (see this answer) You can think of ja as an unsigned comparison. So those negative numbers look like really big numbers that are larger than 7. If you used a jg instruction instead, it should behave more like what you're expecting. It can be thought of as a signed comparison.

Josiah Keller
  • 3,635
  • 3
  • 23
  • 35
  • Careful: JA is based on CF, not SF. So it's the carry-out that matters, not the top bit of the `sub` result. For small positive inputs those happen to be the same thing, but it's not true in general. – Peter Cordes Sep 11 '18 at 01:06