AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-29858262

Pato's questions

Martin Hope
Pato
Asked: 2025-03-06 02:47:11 +0800 CST

68000 汇编 - 在排序程序中通过堆栈传递参数

  • 7

我正在用68000 汇编实现排序算法,并决定使用堆栈将参数传递给交换数组中两个元素的子例程。我想确保正确高效地处理堆栈。

具体来说,在调用SWAP_SUB子程序之前,我使用 将两个元素的地址推送到堆栈pea.l,然后使用 的偏移量在子程序内部检索它们A7。

完整代码如下:

      ORG $8000

START:
      moveq.l #len-1,d7  
OUTER_LOOP:
      lea.l array,a0     
      moveq.l #len-2,d6  

INNER_LOOP:
      move.b (a0)+,d2   
      cmp.b (a0),d2
      blt.s DO_SWAP  

NO_SWAP:
      subq.l #1,d6
      bge.s INNER_LOOP
      
      subq.l #1,d7
      bge.s OUTER_LOOP
      
      SIMHALT

DO_SWAP:
     pea.l (a0)  
     pea.l -1(a0)  
     bsr.s SWAP_SUB  
     addq.l #8,a7  
     bra.s NO_SWAP 

SWAP_SUB: 
     movem.l d3-d4,-(a7) ;new line
                         
     move.l 4(a7),a0  
     move.l 8(a7),a1  
     
     move.b (a0),d3  
     move.b (a1),d4  

     lsl.w #8,d3  
     or.w d4,d3  
     rol.w #8,d3  
     move.w d3,d5  
     lsr.w #8,d5  
     move.b d5,(a0)  
     andi.w #$00FF,d3  
     move.b d3,(a1)  
     
     movem.l (a7)+,d3-d4 ;new line

     rts  

array   DC.B 5,3,8,1,7       
len     EQU 5                

    END START


问题:

  1. 我是否正确使用堆栈传递参数?我的方法是否存在任何潜在问题?
  2. 向子程序传递参数时,是否有设置堆栈的通用方法?
  3. 这段代码能以任何方式简化吗?
assembly
  • 1 个回答
  • 59 Views
Martin Hope
Pato
Asked: 2025-03-04 19:16:06 +0800 CST

68000 汇编 – 通过堆栈传递字符串连接参数

  • 6

我正在开发一个Motorola 68000汇编程序,该程序使用子例程连接两个字符串。挑战在于通过堆栈实现输入和输出的参数传递,因此我专注于正确设置和恢复堆栈。

我在Sep Roland和Erik Eidt的帮助下开发了程序逻辑。之后,我研究了如何使用堆栈传递参数,这就是为什么我的代码有大量注释的原因。

任务要求:

  • 用68000 汇编语言实现一个使用堆栈传递参数的子程序。
  • 该子程序接受两个输入字符串:
    • A ="Hello"
    • B ="World"
  • 它将它们连接成输出字符串C,结果为:
    • C ="HelloWorld"
  • 主程序应该:
    1. 通过推送参数来准备堆栈。
    2. 调用子程序。
    3. 函数返回后正确恢复堆栈。

我的实现:

          ORG $8000
   
;DATA
StringA DC.B 'Hello',0    ; First string with a null terminator
StringB DC.B 'World',0    ; Second string with a null terminator
StringC DS.B 256          ; Buffer for the concatenated string 

START: 

; The stack pointer (A7) starts at address $8000. 
; In the 68000 architecture, A7 always points to the memory address where 
; the next value will be saved (push operation).

      pea.l StringC ; Equivalent to [move.l #StringC, -(a7)]
                    ; The stack pointer (A7) is decremented by 4 (pushing a longword = 4 bytes)
                    ; Initial A7 = $8000, now A7 = $7FFC
      
      pea.l StringB  ; A7 = $7FF8
      pea.l StringA  ; A7 = $7FF4

; Therefore, the stack (from lowest to highest address) contains:
; A7 = $7FF4  |StringA address| 
; A7 = $7FF8  |StringB address| 
; A7 = $7FFC  |StringC address| 
; A7 = $8000 (original SP value before the push operations)

      bsr.s CopyStrings     ; Call the first subroutine, saving the PC (Program Counter)
                            ; onto the stack
                                
; When executing bsr.s, the processor:
; - Saves the return address (PC) on the stack (another 4 bytes subtracted from A7).
; - Then branches to CopyStrings.

; Upon returning from the subroutine (rts), the stack pointer A7 will remain 
; where the subroutine left it. However, we need to clean up the three parameters 
; (StringA, StringB, StringC) that we previously pushed.

      addq.l #8,a7  ; Restore 8 bytes of the stack
      addq.l #4,a7  ; Restore the remaining 4 bytes (total 12 bytes)

      SIMHALT 

CopyStrings:
      ; At the entry of the subroutine, the stack looks like this:
      ; A7    |Return Address | 
      ; A7+4  |StringA Address| 
      ; A7+8  |StringB Address| 
      ; A7+12 |StringC Address|
      
      move.l 4(a7),a0  ; Retrieve the address of StringA 
      move.l 8(a7),a1  ; Retrieve the address of StringB
      move.l 12(a7),a2 ; Retrieve the address of StringC 
      
CopyA: 
      move.b (a0)+,(a2)+  ; Load a character from StringA into StringC
                          
      bne.s CopyA         ; If the character is not null, continue copying
      subq.l #1,a2        ; Move back 1 byte to overwrite the null terminator

CopyB:
      move.b (a1)+,(a2)+  ; Load a character from StringB into StringC
      bne.s CopyB         ; If the character is not null, continue copying
      rts                 ; Return from subroutine
    
     END START

问题:

  1. 我通过堆栈传递参数的方法正确吗?
  2. 我应该考虑哪些优化或最佳实践?

任何反馈都将不胜感激!

assembly
  • 2 个回答
  • 27 Views
Martin Hope
Pato
Asked: 2025-03-03 19:05:04 +0800 CST

68000 汇编 - 字符串连接子程序

  • 6

我正在用汇编语言为 Motorola 68000 编写一个子程序,用于连接两个字符串。该子程序接收两个输入字符串StringA("Hello") 和StringB("World"),并将连接结果存储在StringC("HelloWorld") 中。

代码编译时没有错误,似乎可以工作,但我不确定输出是否正确或实现是否在逻辑上正确。

我写了以下代码:

    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

问题:

  • 我的子程序实现正确吗?我使用了jsr和rts,但我想确认这是否是此上下文中的最佳方法。
  • 可以以任何方式进行优化吗?例如,我可以删除哪些冗余指令?
assembly
  • 2 个回答
  • 67 Views
Martin Hope
Pato
Asked: 2025-03-03 04:16:33 +0800 CST

68000 汇编 - 查找数组中的最小值

  • 6

我正在用M68K汇编语言编写一个程序来查找数组中的最小值。

这是我的代码:

ORG $8000

; DATA
array DC.B 2,3,1,4,5  ; The minimum is 1
len EQU 5
min DC.L 0          ; Stores the found minimum

START:
     lea.l array,a0
     move.b (a0)+,d0   ; d0 = 2 (current minimum), a0 now points to 3
     moveq.l #len-1,d1 ; One element already used

LOOP: 
    cmpi.l #0,d1       ; If d1 = 0, no more elements to check
    beq.s END          ; Jump to the end if finished
    
    move.b (a0)+,d2    ; Load next element into d2
                       ; d2 = 3, a0 -> 1
                       ; d2 = 1, a0 -> 4
                       ; d2 = 4, a0 -> 5
                       ; d2 = 5, a0 -> ??? (What happens here?)
                       
    cmp.b d0,d2 
    blt.s UPDATE       ; If d2 < d0, update minimum

    bra.s DECREMENT

UPDATE:
     move.b d2,d0      ; Update the minimum

DECREMENT:
     subq.l #1,d1      ; Decrease counter
     bra.s LOOP

END: 
    move.b d0,min   ; Store the minimum
    SIMHALT
    END START

我的问题:

  1. 在我标记的位置,处理完最后一个元素5???后会发生什么?它是否指向无效地址?a0
  2. 我的初始化方法是否是d0一个move.b (a0)+,d0好的开始方式,或者是否有更好的方法?
  3. 我的代码还可以进一步优化吗?

任何建议都将不胜感激!谢谢!

assembly
  • 1 个回答
  • 54 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve