我编写了一个代码,用于计算一个三角形区域,该区域在两个寄存器(R16和R18)中加载了基数和高值。这些是8位值
.include "./m2560def.inc"
;------------------------------------------------------------------
; Constants
;------------------------------------------------------------------
.def base = r16
.def high = r17
.equ base_value = 10
.equ high_value = 20
.cseg
.org 0x0000
rjmp reset ; reset intr
reset:
LDI R16, HIGH(RAMEND)
OUT SPH, R16
LDI R16, LOW(RAMEND)
OUT SPL, R16
RCALL configure_ports
start:
LDI base, base_value
LDI high, high_value
MUL base, high
MOVW R18, R0
LSR R18 ;divide by 2
MOV R19, R18
OUT PORTB, R19 ;Output result in PORTB
OUT PORTD, R19 ;Output result in PORTD
RJMP start
configure_ports:
;Configurare B and C ports as outputs
LDI R16, 0XFF
OUT DDRB, R16
OUT DDRC, R16
ret
如果我使用16位数字作为基数和高位,如何将其加载到两个寄存器中并计算16位的(基数x高)和(基数x高)/ 2操作?
答案 0 :(得分:0)
如果您了解如何在纸上执行十进制乘法,那么将很容易用8位数字替换十进制数字。
假设您有两个十进制数字:AB和XY(其中A,B,X,Y是十进制数字)。 您可以将其表示为两位数乘以一位数的和:
AB * XY =(AB * Y)+((AB * X)<< 1d)(其中<< 1d表示左移一位数字,等于十进制的10乘)
两位数与一位数的乘积可以用与
相同的术语表示AB * Y =(B * Y)+((A * Y)<< 1d)
或整个扩展可以写为:
AB * XY =(B * Y)+((A * Y)<< 1d)+((B * X)<< 1d)+((A * X)<< 2d)
现在,假设以上示例中的每个数字都是一个字节,您就可以从十进制转换为基于256的系统。
因此,要查找AB * XY的乘法,您需要:
在assmbler中,它可能如下所示: 假设我们有:
代码如下:
clr r16 // a zero register, we'll need it in the future
mul r24, r22 // r1:r0 = r24 * r22
movw r0, r18 // move result to r19:r18
clr r20 // clear r21 and r22
clr r21
mul r24, r23 // r1:r0 = r24 * r23
add r19, r0 // add to the result starting from the second from the right byte (r19)
adc r20, r1 // add next byte with carry
adc r21, r16 // add zero with carry
mul r25, r22 // r1:r0 = r25 * r22
add r19, r0 // add to the result starting from the second from the right byte (r19)
adc r20, r1 // add next byte with carry
adc r21, r16 // add zero with carry
mul r25, r23 // r1:r0 = r25 * r23
add r20, r0 // add to the result starting from the third from the right byte (r20)
adc r21, r1 // add next byte with carry
干得好!现在,您在r21:r20:r19:r18有了四字节的结果
要除以2,您只需将结果1二进制位置向右移动即可。您需要两个说明:
代码:
lsr r21
ror r20
ror r19
ror r18
现在将四字节值除以2(向下舍入)