Electronic – How does the BRGE instruction work in assembly? Why is this code not functioning properly

assemblyavr

.cseg
ldi r16, 0x01
ldi r17, 0x01


add r16,r17
cpi r16,0xFF
brge greater
jmp less


greater:inc r1
        jmp done

less:   jmp done

done: jmp done

I'm writing some assembly code in AVR studio 4, and I'm not sure how the branch works. When I compare r16 (which should have the value 2) with the value 255 in hex, the branch brge (greater than or equal to) jumps to the "greater" label, which then increments r1 to indicate that the value was greater than 255. This doesn't make sense as 2 is not greater than 255. What am I doing wrong?

Best Answer

BRGE is a signed branch instruction, meaning it interprets the arguments as signed numbers represented in Two's Complement format. For 8 bit numbers the values of twos complement range from -128 (1000 0000) to +127 (0111 1111)

In order for your code to work as intended with hex literals you need to use the unsigned branch comparison operator BRSH, which does an unsigned comparison.

For all available branch instructions you can peruse this list on the atmel website.

Most branch instruction will work by checking a status flag that is set by a previous operations, BRGE and BRSH check the signed flag and carry flag respectively. The convenience of two's complement signed numbers (that the architecture exploits) is that arithmetic operations are performed identically to unsigned numbers - so it only comes down to how you interpret the operands and results. The cpi command is agnostic to signed or unsigned numbers and will set both flags for the compare. The branch instruction will then check one or the other