4
mov eax, ptr_to_num1 ; little endian
mov ebx, ptr_to_num2 ; little endian
xor ecx, ecx
xor edx, edx
clc
bytes_addition:
    mov dl, byte [eax+ecx] ; byte from shortest
    adc dl, byte [ebx+ecx]
    mov byte [eax+ecx], dl
    inc ecx
    cmp ecx, 4 ; counter, 
    jl bytes_addition

Consider at

EAX: 4F2252FF (big endian)

EBX: 00DFFC00 (big endian)

The result of this addition is wrong: 50024fff (big endian). It should be 50024eff. It looks like the carry flag is affected, but why?

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
Andrew
  • 63
  • 1
  • 9
  • If you're going to use that `cmp` in the loop you need to move your `clc` to the top of the loop. – David Hoelzer Dec 13 '15 at 21:53
  • I don't think so... This will always set carry to 0, but i use ADC. – Andrew Dec 13 '15 at 22:01
  • My point is that `CMP` will modify the carry flag. This means that it won't necessarily be in the state you expect it to be when the loop starts its next pass. – David Hoelzer Dec 13 '15 at 22:11
  • See http://stackoverflow.com/questions/32084204/problems-with-adc-sbb-and-inc-dec-in-tight-loops-on-some-cpus for discussion of how to loop without affecting the carry flag, and also without causing a partial-flag stall while doing it. (e.g. LEA/JECXZ). In your case, a full unroll of the loop (4x `adc/mov`) would be about as many instructions as your loop. – Peter Cordes Dec 14 '15 at 23:50

1 Answers1

6

cmp affects carry, which is how it's used for unsigned comparison.

You could start ecx at -4, then use jnz bytes_addition. You already have the inc there, which will set the zero flag when ecx becomes zero, and won't affect carry.

Of course this offset has to be compensated for, either by adding 4 to eax before the loop, or adding offsets of 4 in the addressing.

harold
  • 61,398
  • 6
  • 86
  • 164