Assembly 使用AVR汇编程序添加两个32位浮点数

Assembly 使用AVR汇编程序添加两个32位浮点数,assembly,floating-point,avr,32-bit,single-precision,Assembly,Floating Point,Avr,32 Bit,Single Precision,我正在尝试使用AVR Studio将两个32位浮点数相加。我知道我需要将32位数字存储在4个独立的8位寄存器中。然后,我需要使用进位标志将寄存器添加到一起。这就是我目前所拥有的。我添加了5.124323和2.2134523 ;5.124323 (01000000101000111111101001110100) ;Store hex value (40A3FA74) ldi r21,$40 ldi r22,$A3 ldi r23,$FA ldi r24,$74 ;2.2134523 (010

我正在尝试使用AVR Studio将两个32位浮点数相加。我知道我需要将32位数字存储在4个独立的8位寄存器中。然后,我需要使用进位标志将寄存器添加到一起。这就是我目前所拥有的。我添加了5.124323和2.2134523

;5.124323 (01000000101000111111101001110100)
;Store hex value (40A3FA74)
ldi r21,$40
ldi r22,$A3
ldi r23,$FA
ldi r24,$74


;2.2134523 (01000000000011011010100100110100)
;Store hex value (400DA934)
ldi r25,$40
ldi r26,$0D
ldi r27,$A9
ldi r28,$34


;Add the corresponding bytes together including the carry flag
add r21,r25
adc r22,r26
adc r23,r27
adc r24,r28

这似乎没有给我正确的答案。。。我很确定这里唯一的错误是最后4行代码中寄存器的顺序。或者,add/adc功能也可能是错误的。有人能帮我解决这个问题吗?

正如Michael在评论中指出的,您正在对这两个数字执行常规的旧整数加法。您使用的算法假定您的数字是无符号或有符号(二的补码)数字

在真正考虑如何将浮点数相加之前,您需要弄清楚浮点数的格式。浮点数通常用指数、尾数和符号位表示。这些可能取决于您使用的确切编译器及其设置。也许你的编译器的浮点数符合。或者,如果这些浮点数不是来自任何编译器,那么您应该找出生成它们的代码,并研究这些代码,以便了解它们的格式

您应该重新考虑是否真的需要浮点数。也许整数已经足够好了

如果您确实需要浮点数,您应该尝试编译一个执行浮点加法的C程序,然后将其反汇编列表作为起点。

大多数CPU(包括AVR)不存储类型信息,因此您必须对不同的类型使用不同的指令<代码>为整数添加和adc,为浮点添加不同的指令

如果CPU没有浮点指令,那么可能会有一个库子程序来为您执行



有趣的是,您可以对有符号(2s补码)和无符号使用相同的加法。但不是相同的乘法或除法 您无法获取浮点位并简单地将它们相加以获取结果的浮点,它们不是十进制或十六进制数

浮点数字系统吓坏了很多人,它是一种不同的表示数值的方式,对于用巨大或微小的数字进行计算非常有用。我们在小学、中学甚至大学都没有学到这一点。没有能够处理FP数字的袖珍卡西欧计算器,因此我们对这些数字并不十分熟悉,我们孤身一人在黑暗中

大多数程序员(如果不是全部的话)更喜欢将FP留给C/C++编译器处理,他们不按位处理FP,对一些人来说这就像瘟疫一样。无论如何,FP是由人类创造的(真正的问题),即使如此,还是有办法解决它

我在这里的目的不是教你如何在AVR汇编中实现它,即使这是完全可能和容易的,如果你遵循我下面的解释。我在这里的意图是要表明“老虎”不是怪物,它是一只蓝色眼睛的小宠物猫,但它仍然是一只有牙齿和爪子的猫

您将在下面找到:

1。浮点运算的精髓
2。容易的浮点乘法容易
3。浮点加法(您的问题)

勇气:

是单精度和双精度FP,32位和64位,让我们剥离32位

FP编号有3个分区:

a) 符号,1位,#32(左一),零表示正,一表示负。
b) 指数,8位,这里是老虎捕猎的地方,人们很困惑。
c) 尾数,23位,指数分数补足

为了能够表示一个非常大或非常小的数字,中心将为1,因此,当指数的第7位(我们称之为“7E”)为1时,数字为1或更大。7E=1的数字大于等于1,7E=0的数字小于1(例如0.7)

在考虑指数的位值时,不需要将7E计算为一个带值的实位,有些人会这样做。从现在起,我们将只处理大于1且为正数的数字,所以我不会对7E或符号位进行评论,甚至不会将其作为指数值

指数和尾数是二进制计数的。指数位的值与常规二进制数相同,不同之处在于位值总是加上1,E1=2,E2=3,E2+E1=4,E3=5。。。所有位E1至E6 on=128

指数表示法的值为2^n,其中“n”是上述位或位组合的值。最小值为2^-126,这是一个非常小的数字,最大值为2^128,这是一个被认为是无穷大的巨大数字,2^127有39位数字

E7.6.5.4.3.2.1.0   
 1 0 0 0 0 0 0 0 = decimal 0, but remember, it needs to add 1, so it is 1, and the value is 2^1 = 2

E7.6.5.4.3.2.1.0   
 1 0 0 0 0 0 0 1 = decimal 1, +1 = 2, 2^2 = 4   
 1 0 0 0 0 0 1 0 = decimal 2, +1 = 3, 2^3 = 8   
 1 0 0 0 0 0 1 1 = decimal 3, +1 = 4, 2^4 = 16   
 1 0 0 0 0 1 0 0 = decimal 4, +1 = 5, 2^5 = 32   
 1 0 0 0 0 1 0 1 = decimal 5, +1 = 6, 2^6 = 64   
 1 0 0 0 0 1 1 0 = decimal 6, +1 = 7, 2^7 = 128   
 1 0 0 0 0 1 1 1 = decimal 7, +1 = 8, 2^8 = 256   
 1 0 0 0 1 0 0 0 = decimal 8, +1 = 9, 2^8 = 512   
 1 0 0 1 0 0 0 0 = decimal 16, +1 = 17, 2^17 = 131072   
 1 0 0 1 0 0 0 1 = decimal 17, +1 = 18, 2^18 = 262144   
观察指数加1乘以其值2。
倒数是真的,减去1,指数除以2

10000100=32,减去1,变成10000011=16

同样,向左移动一位并加1,乘以指数本身,即N^2。 例如,1000010=8,向左移动10000100=32,加上10000101=64=8^2。
所以,向左移动=N*N/2

只有当位E1(指数的最后一位)为1时,倒数才为真,10000101(64)减去1并向右移动的情况下,将得到平方根1000010(8)。10001011(4096)减去1,右移为10000101=64。如果E1=0,结果无效,10000110(128)减去1,10000101和右移的情况变为10000010,即8,如果只有不减去的移位变为10000011,即16,则两者均无效

强化理念:
0000-1110在二进制中表示2^3+2^2+2^1=8+4+2=14。
x0
Bit 23 = 0.5  (left bit)   
Bit 22 = 0.25   
Bit 21 = 0.125    
Bit 20 = 0.0625   
Bit 19 = 0.03125   

...   
...   
Bit 1 = 0.0000001192092896 (bit FP 1)  
6  = FP 0-10000001-1000000000...   
8  = FP 0-10000010-0000000000....   
14 = FP 0-10000010-1100000000.... 
0.1100000000    
1.0000000000   
--=--------- +   
1.1100000000   
Your number A = 5.1243230 FP 0-10000001-01000111111101001110100   
your number B = 2.2134523 FP 0-10000000-00011011010100100110100   
Result A + B  = 7.3377753 FP 0-....  
A = 1.01000111111101001110100   
B = 1.00011011010100100110100   
A = 1.01000111111101001110100   
B = 0.10001101101010010011010 
A = 1.01000111111101001110100   
B = 0.10001101101010010011010   
------------------------------ +   
    1.11010101100111100001110   
7 FP  0-10000001-11000~
2 FP  0-10000000-00000~
7 Mantissa:  1.110000~
2 mantissa:  1.000000~
7 Mantissa:  1.110000~
2 mantissa:  0.100000~
----------------------- +
Resulting:  10.010000~