如果一个用C编码的嵌入式系统是8或16位的,它将如何处理像int这样的32位数据类型



我认为我的想法是错误的,但我想知道一个小于32位的嵌入式系统如何使用32位数据值。我是一个初学者,所以对我宽容一点:)

基本10

0100  <- carry in/out  
5432
+1177
======
6609

从未在课堂上提起过,但我们现在可以将其扩展到的两个操作

100 
32
+77
======
09
01
54
+11
======
66

并得出6609的结果,因为我们知道它是基于列的,并且每个列都被单独处理。

基本2

1111
+0011
=====
11110 
1111
+0011
=====
10010
110 
11
+11
=====
10
111 
11
+00
=====
100

结果10010

你可以把你的操作分解成你想要的任何比特,8,16,13,97。它是基于列的(用于添加),它只是起作用。除法你应该能够算出,乘法只是移位和加法,可以把它变成多次运算

n位*n位=2*n位,所以如果你有一个8位*8位=16位的乘法,你可以在8位系统上使用它,否则你必须限制为4位*4位=8位并使用它(或者如果没有乘法,那么只进行移位和加法)。

基本2

abcd
*   1101
========
abcd
0000
abcd
+abcd
=========

您可以将其分解为移位和添加问题,可以使用4、8或M位处理器/寄存器/alu 来处理N位

或者换个角度来看,小学代数

(a+b)*(c+d)=ac+bc+ad+bd

mnop*tuvw=((mn*0x100)+(op))*((tu*0x100(vw))=(a+b)*(c+d)

你应该会发现,你可以将带0x100项和不带0x100的项组合起来,在不使用8位alu(或根据需要使用8位中的4位)将答案的各部分组合在一起的情况下,分别进行这些操作。

移位应该是显而易见的,只需将位移到下一个字节或(半)字或其他什么。

而按位操作(xor,and,or)是按位的,所以不需要任何特殊的操作,只需将列排列即可。

编辑

或者你可以试试

unsigned long fun1 ( unsigned long a, unsigned long b )
{
return(a+b);
}
00000000 <_fun1>:
0:   1166            mov r5, -(sp)
2:   1185            mov sp, r5
4:   1d40 0004       mov 4(r5), r0
8:   1d41 0006       mov 6(r5), r1
c:   6d40 0008       add 10(r5), r0
10:   6d41 000a       add 12(r5), r1
14:   0b40            adc r0
16:   1585            mov (sp)+, r5
18:   0087            rts pc
00000000 <fun1>:
0:   0e 5c           add r12,    r14 
2:   0f 6d           addc    r13,    r15 
4:   30 41           ret 
00000000 <fun1>:
0:   62 0f           add r22, r18
2:   73 1f           adc r23, r19
4:   84 1f           adc r24, r20
6:   95 1f           adc r25, r21
8:   08 95           ret

如果你能理解这些指令集,就可以获得额外的积分。

unsigned long fun2 ( unsigned long a, unsigned long b )
{
return(a*b);
}
00000000 <_fun2>:
0:   1166            mov r5, -(sp)
2:   1185            mov sp, r5
4:   10e6            mov r3, -(sp)
6:   1d41 0006       mov 6(r5), r1
a:   1d40 000a       mov 12(r5), r0
e:   1043            mov r1, r3
10:   00a1            clc
12:   0c03            ror r3
14:   74d7 fff2       ash $-16, r3
18:   6d43 0004       add 4(r5), r3
1c:   70c0            mul r0, r3
1e:   00a1            clc
20:   0c00            ror r0
22:   7417 fff2       ash $-16, r0
26:   6d40 0008       add 10(r5), r0
2a:   7040            mul r0, r1
2c:   10c0            mov r3, r0
2e:   6040            add r1, r0
30:   0a01            clr r1
32:   1583            mov (sp)+, r3
34:   1585            mov (sp)+, r5
36:   0087            rts pc

8位系统可以在单个指令和单个内存访问中执行8位操作,在这样的8位系统上,16和32位操作需要额外的数据访问和额外的指令。

例如,典型的体系结构将算术结果放在寄存器中(通常是累加器,但有些体系结构更正交,可以使用任何寄存器获取结果),算术溢出导致进位标志设置在状态寄存器中。在比本机架构更大的操作中,代码可以检查进位标志,以便在后续指令中采取适当的操作。

比方说,对于一个8位系统,你把1加到255,8位累加器的结果将为零,进位标志设置;则下一个指令可以响应进位标志向16位值的高位字节加1。这可以波及到任何数量的字节或字,这样系统就可以处理任意比特长度的操作,而不是在单个指令操作中处理底层架构的操作。

最新更新