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

Motorola 68000汇编字符串拼接子程序正确性与优化问询

Motorola 68000字符串拼接子程序的正确性与优化分析

问题背景

我编写了一个Motorola 68000汇编的字符串拼接子程序,接收两个带空终止符的输入字符串StringA("Hello")和StringB("World"),将拼接结果存入StringC。代码编译无错误,但不确定输出是否正确、实现逻辑是否严谨,同时有两个疑问:

  1. 子程序实现是否正确?jsr和rts的使用是否是该场景下的最佳方式?
  2. 代码是否可优化?有没有冗余指令可以移除?

编写的汇编代码

ORG $8000
     
StringA DC.B 'Hello',0    ; First string with null terminator
StringB DC.B 'World',0    ; Second string with null terminator
StringC DS.B 20           ; Buffer for the concatenated string (large enough?)

START: 
      lea.l StringA,a0    ; a0 -> "Hello"
      lea.l StringB,a1    ; a1 -> "World"
      lea.l StringC,a2    ; a2 -> Buffer for concatenation
      clr.b d0            

      jsr CopyA           ; Call first subroutine 
      
      SIMHALT             

CopyA: 
      move.b (a0)+,d0     ; Load character from StringA into d0
                          ; Check if it is the null terminator
      beq.s CopyB         ; If yes, start copying StringB
      move.b d0,(a2)+     ; Otherwise, copy character into StringC
      bra CopyA           
      
CopyB:
      move.b (a1)+,d0     ; Load character from StringB into d0
      move.b d0, (a2)+    ; Copy it into StringC
      bne CopyB           ; If the character is not null, continue copying
     
     rts                  ; Return from subroutine
    
     END START

问题解答

1. 子程序正确性与jsr/rts的使用

实现完全正确

你的代码逻辑没问题,最终StringC会得到"HelloWorld\0"的正确结果:

  • CopyA循环复制StringA的每个字符,碰到空终止符就跳转到CopyB
  • CopyB会把StringB的所有字符(包括结尾的空终止符)都复制到StringC,直到复制到空终止符后退出返回

关于StringC的大小:算上两个字符串的字符和各自的空终止符,总共需要12字节,你分配了20字节,完全足够,不会出现缓冲区溢出问题。

jsr/rts使用合理但非必须

用jsr和rts把拼接逻辑封装成子程序是合理的——代码结构清晰,要是以后需要多次拼接字符串,直接调用就行。但如果这个拼接逻辑只需要执行一次,也可以把CopyA和CopyB的代码直接写到START里,省掉一次子程序调用的开销(虽然68000的这个开销不大,但追求极致性能的话可以这么做)。不过从可读性和维护性来说,封装成子程序是更好的选择。

2. 代码优化:移除冗余与精简逻辑

你的代码有两处可以优化的地方:

  • 删除冗余的clr.b d0
    START里的clr.b d0完全没用,因为进入CopyA后第一条指令就是move.b (a0)+,d0,直接覆盖了d0的内容,这条指令可以直接删除。
  • 使用短分支节省指令长度
    CopyA里的bra CopyA可以改成bra.s CopyA,用短分支指令(占2字节,长分支占4字节),因为CopyA是本地标签,短分支足够到达。同样CopyB里的bne CopyB也可以改成bne.s CopyB。

另外,CopyB还可以改成无需d0中转的写法,性能和原写法差不多,看你偏好可读性:

CopyB:
      move.b (a1)+,(a2)+  ; 直接把StringB的字符复制到StringC
      tst.b -(a2)         ; 检查刚复制的字符是不是空终止符
      bne.s CopyB         ; 不是就继续
      addq.l #1,a2        ; 把a2指针回退到正确位置

优化后的完整代码:

ORG $8000
     
StringA DC.B 'Hello',0    ; First string with null terminator
StringB DC.B 'World',0    ; Second string with null terminator
StringC DS.B 20           ; Buffer for the concatenated string (large enough?)

START: 
      lea.l StringA,a0    ; a0 -> "Hello"
      lea.l StringB,a1    ; a1 -> "World"
      lea.l StringC,a2    ; a2 -> Buffer for concatenation

      jsr CopyA           ; Call first subroutine 
      
      SIMHALT             

CopyA: 
      move.b (a0)+,d0     ; Load character from StringA into d0
      beq.s CopyB         ; If null terminator, jump to copy StringB
      move.b d0,(a2)+     ; Copy character to StringC
      bra.s CopyA         ; Short branch for efficiency
      
CopyB:
      move.b (a1)+,d0     ; Load character from StringB into d0
      move.b d0,(a2)+     ; Copy to StringC
      bne.s CopyB         ; Continue if not null
     
     rts                  ; Return from subroutine
    
     END START

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 02:10:07