You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ATmega328汇编:仅用加法指令实现8位乘8位得16位结果求助

ATmega328汇编乘法代码MSB计算错误修正

我是大学汇编新手,用Atmel Studio模拟ATmega328架构,需要用add/adc指令实现两个8位数字(0b00111010和0b01010101)的乘法,得到16位结果。现在GPT生成的代码只能正确计算结果的LSB,MSB计算错误,怀疑问题出在adc r19, r1这一行,请求帮忙排查修正。

原代码:

; Input r16 (00111010), r17 (01010101)
; Output r18:r19 (risultato)

    ldi r16, 0b00111010   ; Load first number in r16
    ldi r17, 0b01010101   ; Load second number in r17

    ldi r18, 0            ; Initialize LSB's resoult to 0
    ldi r19, 0            ; Initialize MSB's resoult to 0

    ldi r20, 8            ; 8 bit counter

multiply_loop:
    lsr r17               ; Shift to dx the first number
    brcc no_add           ; Skip if the LSB is 0

    add r18, r16          ; Add first number to the lower part of the resoult
    adc r19, r1           ; Add carry to the higher part of the resoult

no_add:
    lsl r16               ; Left shift of first number

    dec r20               ; Decrease counter
    brne multiply_loop    ; Repeat cycle until counter is 0

    ; Final resoult in r18:r19

错误原因分析

  1. 被乘数存储位数不足:原代码仅用8位寄存器r16存储被乘数,左移超过7位后,溢出的高位会被丢弃。例如计算58×64时,实际值为3712(十六进制0xE80),但r16只能存储低8位0x80,高位0xE丢失,导致相加时仅加了低8位,MSB计算缺失。
  2. 高位相加逻辑不完整:adc r19, r1仅处理了add r18, r16产生的进位,但没有将被乘数移位后的高位部分加到结果MSB中,这也是MSB错误的直接原因。

修正后的代码

; Input r16 (00111010), r17 (01010101)
; Output r18:r19 (结果,r19为MSB,r18为LSB)

    ldi r16, 0b00111010   ; 被乘数低8位
    ldi r15, 0            ; 被乘数高8位,初始化为0
    ldi r17, 0b01010101   ; 乘数

    ldi r18, 0            ; 初始化结果低8位
    ldi r19, 0            ; 初始化结果高8位

    ldi r20, 8            ; 8位循环计数器

multiply_loop:
    lsr r17               ; 乘数右移,LSB移入进位标志C
    brcc no_add           ; 若C=0(原LSB为0),跳过相加步骤

    add r18, r16          ; 结果低8位 += 被乘数低8位
    adc r19, r15          ; 结果高8位 += 被乘数高8位 + 上一步的进位

no_add:
    lsl r16               ; 被乘数低8位左移,溢出位移入C
    adc r15, r1           ; 被乘数高8位 += 0 + C,完成16位整体左移

    dec r20               ; 计数器减1
    brne multiply_loop    ; 计数器不为0则继续循环

    ; 最终结果存储在r19:r18中

修正说明

  • 用16位寄存器对r15:r16存储被乘数,通过lsl r16+adc r15, r1实现完整的16位左移,保留移位后的所有高位。
  • 相加时使用add r18, r16+adc r19, r15,将16位的被乘数移位值完整加到结果寄存器对中,同时处理进位。
  • 修正后代码执行结果为r19=0x13、r18=0x42,对应十进制4930,与58×85的正确结果一致。

内容的提问来源于stack exchange,提问作者Alessandro Pascale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:00:57