【发布时间】:2016-01-30 22:29:42
【问题描述】:
我正在尝试了解如何在 avr 程序集中的 2 个 16 位数字之间进行有符号加法。
鉴于此 C 代码:
#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 输出(简化为更具可读性):
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
我知道x 的低字节在r24 中,高字节在r25 中。此外,返回值在相同的寄存器中。 r18 和 r19 存储 y 的低字节和高字节。
我的问题是:在积极的情况下,r18 和 r19 得到 16 和 39 (39*256+16==10000) 但为什么在消极的情况下他们得到 -40 而不是 -39?
带符号的多字节数一般如何表示,如何相加?
【问题讨论】:
-
-40 是 216 无符号,-16 是 240 无符号,这给出 55536 无符号,即 -10000 有符号。或者换句话说,-10000 是 0xD8F0 十六进制,它具有给定的低字节和高字节。见two's complement。加法本身的工作原理相同。
-
加法和减法没有有符号或无符号的概念。乘法和除法,当然,但加法和减法不是。部分互补之美。