I am trying to understand how to do signed addition between 2 16-bit numbers in avr assembly.
Given this C code:
#include <stdbool.h>
int16_t my_fun(const int16_t x, bool is_positive){
const int16_t y = 10000 * (is_positive? 1 : -1);
return x + y;
}
avr-gcc
outputs (simplified to be more readable):
my_fun:
cpse r22,r1
rjmp positive
ldi r18,-16
ldi r19,-40
rjmp add_them
positive:
ldi r18,16
ldi r19,39
add_them:
add r24,r18
adc r25,r19
ret
I understand that x
's lower byte is in r24
and higher byte in r25
. Also, the return value is in the same registers. r18
and r19
store y
's lower and higher byte.
My questions are: in the positive case r18
and r19
get 16
and 39
(39*256+16==10000
) but why do they get -40
instead of -39
in the negative case?
How do signed multi-byte numbers are represented in general and how do we add them?