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
    • 最新
    • 标签
主页 / coding / 问题

问题[assembly](coding)

Martin Hope
da pig
Asked: 2025-04-09 19:01:10 +0800 CST

IBM AIX 6.1 PPC 汇编程序在使用 .text 和 as 时出现编译问题

  • 5

我正在尝试在 AIX 6.1 中使用“as”和“ld”编写程序。但是却无法正常工作。目前有两个问题阻碍了我继续前进。

在下面的代码中,当我使用“as hello.s -o hello.o”进行编译时,.text 部分会引发错误消息:-

.text
.globl main
main:
        addi    3, 0, 1
        addi    4, 0, 2
        add     5, 3, 4
        blr

错误 hello.s: 第 1 行: 1252-016 指定的操作码或伪操作无效。请仅使用支持的指令或伪操作。

当我删除“.text”行时,源代码编译没有问题。但是,在使用“ld -e main hello.o -o hello”创建可执行文件后,尝试执行时出现以下错误:

exec(): 0509-036 无法加载程序 hello,因为出现以下错误:0509-026 系统错误:内存地址不在进程的地址空间中。

'ldd' 显示没有依赖关系,因此空的 LIBPATH 和 LD_LIBRARY_PATH 似乎不是问题

‘dbx 你好’:-

输入“help”获取帮助。

警告:无法执行 hello

正在读取符号信息...程序未激活

警告:没有使用 -g 编译的源

程序未激活

建筑信息:-

处理器类型:PowerPC_POWER8

处理器实现模式:POWER 7

处理器版本:PV_7_Compat

CPU类型:64位

内核类型:64位

先感谢您。

assembly
  • 1 个回答
  • 50 Views
Martin Hope
EnzoR
Asked: 2025-04-08 01:40:43 +0800 CST

为什么 RISC-V gcc 会在返回结构的函数中创建无用的指令来保留堆栈空间?

  • 8

此 C 源代码:

typedef struct {
  unsigned long one;
  unsigned long two;
} twin;

twin function( twin t ) {
  return (twin){ 0,0 };
}

生成此程序集:

        .file   "p.c"
        .option nopic
        .attribute arch, "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0"
        .attribute unaligned_access, 0
        .attribute stack_align, 16
        .text
        .align  1
        .globl  function
        .type   function, @function
function:
        addi    sp,sp,-32  # <<< WHY?
        li      a0,0
        li      a1,0
        addi    sp,sp,32   # <<< WHY?
        jr      ra
        .size   function, .-function
        .ident  "GCC: (g04696df09) 14.2.0"
        .section        .note.GNU-stack,"",@progbits

riscv64-unknown-elf-gcc (g04696df09) 14.2.0当通过或-O3或-O2或-O1甚至运行时-Os。

那么为什么代码要在堆栈上为保存在寄存器中的内容(32 字节)创建空间呢a0?a1

这是一个错误,还是我遗漏了什么?

assembly
  • 1 个回答
  • 63 Views
Martin Hope
pts
Asked: 2025-04-03 17:23:44 +0800 CST

如何在不修改FLAGS或regs的情况下检测我的x86代码是在16位模式还是32位模式下运行?

  • 10

我的预编译 x86 代码可能运行在 16 位(实模式或 16 位保护模式)或 32 位(i386 保护模式)下。如何在运行时从代码中检测它?

我能找到这个 NASM 源代码:

bits 16
cpu 386

pushf
test ax, strict word 0  ; In 32-bit mode this is `test eax, ...', +2 bytes.
jmp short found_16
; Fall through to found_32.

found_32:
bits 32
popf
int 32  ; Or whatever code.

found_16:
bits 16
popf
int 16  ; Or whatever code.

但是我不喜欢它,因为它使用了堆栈。有没有一种解决方案,既不修改任何通用寄存器、段寄存器或标志,也不使用堆栈,而且可以在 8086(仅 16 位模式)和 386(两种模式)上运行?

我已尝试lea esi, [dword esi+0]过 32 位模式,但在 16 位模式下则转换为非 nop。


请注意,我知道对于大多数程序来说,模式是在编译时决定的(作为架构和平台的一部分),并且它们不必能够在运行时检测模式。对于正常启动的程序,操作系统也会根据文件头选择正确的模式,因此几乎没有意外以错误模式运行完整程序文件的危险。但是,某些程序片段(例如漏洞利用 shellcode)可以从各种运行时检测中受益(包括架构和操作系统)。我还想到了一些其他不太明显的用例。

assembly
  • 3 个回答
  • 122 Views
Martin Hope
5andr0
Asked: 2025-03-30 16:28:33 +0800 CST

AArch64 指令长度反汇编代码

  • 7

我正在寻找一个非常简约的 ARM64 指令长度反汇编程序,以便我可以遍历函数的一些指令。
我需要一个没有太多依赖项的独立函数,因为我需要它用于内核驱动程序。

对于 x64,我使用的是https://github.com/gh-nomad/length-disassembler/blob/master/ldisasm.cpp,但我找不到适用于 AArch64 的类似程序。有一些完整的反汇编库,但它们带有大量源代码和用户空间依赖项。

我甚至不需要支持任何扩展指令集,比如 SVE

assembly
  • 1 个回答
  • 33 Views
Martin Hope
Ryan Grube
Asked: 2025-03-30 13:07:39 +0800 CST

在 16 位实模式下执行 32 位数字乘法以遍历 FAT 表

  • 7

我正在编写一个简单的引导程序(希望很快能编写一个操作系统)。我一直在取得进展,但这部分有点难倒我。

我正在将此操作系统和引导加载程序写入磁盘映像,其中包括:

  1. MBR 引导扇区和第一阶段引导加载程序
  2. 为第二阶段引导加载程序保留 32kb 区域
  3. 一个包含操作系统的 FAT32 分区,以及kernel.bin

我的目标是将 kernel.bin 加载到内存中并跳转到该位置,为了做到这一点,我必须遍历 FAT 表。

读取 FAT32 分区所涉及的许多逻辑需要 32 位值(如许多 BPB 值)

由于我现在基本上处于实模式,因此我不确定在执行乘法等计算时如何处理这些 32 位数字。我知道我可以使用操作数大小前缀和/或地址大小前缀来使用 32 位寄存器,但我无法以有意义的方式对它们进行算术运算。

例子

以下是存储来自 BPB 的重要值的汇编部分:

BPB_info:

    ; BPB info from the FAT32 boot sector
    BPB_NumFATs: db 0 ; Number of FATs (1 byte)
    BPB_FATSz32: dd 0 ; Size of each FAT in sectors (4 bytes)
    BPB_RootClus: dd 0 ; First cluster of the root directory (4 bytes)
    BPB_SecPerClus: db 0 ; Sectors per cluster (1 byte)
    BPB_RsvdSecCnt: dw 0 ; Reserved sectors count (2 bytes)

    ; Calculated values used in the bootloader
    FAT_root_dir_start: dq 0 ; Start of the root directory in sectors (calculated)
    FAT_lba: dq 0 ; Logical block address of the FAT tables (calculated)

为了计算FAT_root_dir_start,我必须使用以下公式:

BPB_RsvdSecCnt + ((BPB_RootClus - 2) * BPB_SecPerClus)

但由于BPB_RootClus是一个双字(32 位),我不确定如何执行此操作。

任何建议都将不胜感激!我走对路了吗?我应该完全不同地处理这个问题吗?也许切换到保护模式?我不确定。

assembly
  • 1 个回答
  • 58 Views
Martin Hope
sanzenyou
Asked: 2025-03-28 22:09:52 +0800 CST

为什么asm代码中这个字符串里的这些ascii字符会自动减1呢?

  • 4
org 0x7c00

BOOTDRIVE equ 0x9000

flatcode equ 0x0008                             
                                                
flatdata equ 0x0010                                 
                                                
flatstack equ 0x0010                                

[bits 16]

section .text

bspstart:
    
    xor ax,ax       ;some BIOS required
    
    mov ds,ax
    mov byte [BOOTDRIVE],dl
    
    mov ax,0x8000
    mov ss,ax
    mov sp,0

    mov cx,2000 ;80x25*2
    xor si,si
    mov di,1
    mov ax,0xb800
    mov ds,ax
    
cleanscreen:

    mov byte [ds:si],0x0
    add si,2
    mov byte [ds:di],0xf
    add di,2
    
    loop cleanscreen
    
    xor ax,ax
    mov ds,ax       ;restore ax to load GDTR
    
Read_Disk_INT0x13:  ;Read/Write Harddisk/Floppy provided by BIOS INT 0x13   ;cannot use in 32bits mode and 64bits mode
    
    mov ah,0x2  ;function ID 0x2 read_sector; 0x3 write_sector
    mov al,0x2  ;count of read/write sector
    mov ch,0x0  ;location(cylider)
    mov dh,0x0  ;location()
    mov cl,0x2  ;location(sector)
    mov byte dl,[BOOTDRIVE] ;type of drive(0x0~0x7f floppy drive;0x80~0xff hard drive)
    
    mov bx,0x0
    mov es,bx   ;es:bx target memory area 
    mov bx,0x7e00
    
    int 13h
    
    cli             ;after int 0x13 inst execute, the IF bit was enabled. we must to disable it.
    
    jc Read_Disk_Error
    
Read_Disk_OK:
    
    lgdt [GDT_PROP]
    
    in al,0x92
    or al,2
    out 0x92,al
    
    mov eax,0x1
    mov cr0,eax
    
    jmp dword flatcode:bsp_protected_mode_init_segreg

[bits 32]

bsp_protected_mode_init_segreg:

    mov ax,flatdata
    mov ds,ax
    mov ax,flatstack
    mov ss,ax
    
    mov esp,0x00200000
    
loadpage:

    mov eax,flatdata
    mov ds,eax
    mov es,eax
    mov esi,temp_pt
    mov edi,0x00100000
    mov ecx,temp_pt_end - temp_pt
    cld
    rep movsb
    
    mov esi,temp_pdt
    mov edi,0x00101000
    mov ecx,temp_pdt_end - temp_pdt
    cld
    rep movsb
    
    mov esi,temp_pdpt
    mov edi,0x00102000
    mov ecx,temp_pdpt_end - temp_pdpt
    cld
    rep movsb
    
    mov esi,temp_pml4
    mov edi,0x00103000
    mov ecx,temp_pml4_end - temp_pml4
    cld
    rep movsb

bsp_init_long_mode:
    
    call checkcpuid
    
    call checkia32e
    
    mov ax,flatdata
    mov ds,ax
    
    mov eax,0x20
    mov cr4,eax
    
    mov eax,0x00103000      ;pml4
    mov cr3,eax
    
    mov ecx,0xc0000080
    rdmsr
    or eax,1 << 8
    wrmsr
    
    cli
    
    mov eax,0x80000001
    mov cr0,eax
    
    jmp dword flatcode:bsp_long_mode
    
temp_pt:

    dq 0x00000000000b8001
    dq 0x00000000000b8001
    dq 0x0000000000000001
    dq 0x0000000000000001
    dq 0x0000000000000001
    dq 0x0000000000000001
    dq 0x0000000000104001   ;stack at 0x00104000
    dq 0x0000000000007001   ;bootloader
    
temp_pt_end:
    
temp_pdt:

    dq 0x0000000000100001
    
temp_pdt_end:
    
temp_pdpt:
    
    dq 0x0000000000101001
    
temp_pdpt_end:

temp_pml4:

    dq 0x0000000000102001
    
temp_pml4_end:

GDT_PROP:
    
    dw GDT_TABLE_32_END - GDT_TABLE_ENTRY_32 - 1
    dd GDT_TABLE_ENTRY_32
    
GDT_TABLE_ENTRY_32:

    dq 0x0000000000000000   ;Empty Entry
    
    dq 0x00cf9a000000ffff   ;code
    
    dq 0x00cf92000000ffff   ;data&stack
    
GDT_TABLE_32_END:

GDT_PROP_64:
    
    dw GDT_TABLE_64_END - GDT_TABLE_ENTRY_64 - 1
    dq GDT_TABLE_ENTRY_64

GDT_TABLE_ENTRY_64:

    dq 0x0000000000000000
    
    dq 0x00af9a000000ffff
    
    dq 0x00af92000000ffff
    
GDT_TABLE_64_END:


    
[bits 16]

BIOS_13H_ERROR:

    db 'PizzaLoader:(0x0) Disk Error! System Halted.'

Read_Disk_Error:
    
    mov ax,0x0
    mov ds,ax
    
    xor si,si
    
    mov bx,BIOS_13H_ERROR
    
    mov cx,44
    
Print_Disk_Error:
    
    mov dx,0x0
    mov ds,dx
    
    mov byte al,[ds:bx]         ;read BIOS_13H_ERROR
    add bx,1
    
    mov dx,0xb800
    mov ds,dx
    
    mov byte [ds:si],al         ;write 0xb8000
    add si,2
                     
    loop Print_Disk_Error
    
    jmp cpuhlt
    
cpuhlt:

    hlt
    
    
times 510 - ($ - $$) db  0x0

db 0x55, 0xaa

[bits 32]

NO_CPUID_ERROR:

    db 'PizzaLoader:(0x1)The Processor does not support CPUID instruction, System Halted.'

checkcpuid:
    
    pushfd
    pop eax
    
    mov ecx,eax
    
    xor eax,1<<21
    
    push eax
    popfd
    
    pushfd
    pop eax
    
    push ecx
    popfd
    
    xor eax,ecx
    jz nocpuid
    
    ret

nocpuid:
    
    mov ax,flatdata
    mov ds,ax
    
    mov esi,0x000b8000
    
    mov ebx,NO_CPUID_ERROR
    
    mov ecx,81
    
Print_no_CPUID_Error:
    
    mov byte al,[ebx]           ;read NO_CPUID_ERROR
    add ebx,1
    
    mov byte [esi],al           ;write 0xb8000
    add esi,2
                     
    loop Print_no_CPUID_Error
    
    hlt
    
NO_IA32E_ERROR:

    db 'PizzaLoader:(0x2)The Processor does not support 64-bits mode, System Halted.'
    
checkia32e:

    mov eax, 0x80000000    ; Set the A-register to 0x80000000.
    cpuid                  ; CPU identification.
    cmp eax, 0x80000001    ; Compare the A-register with 0x80000001.
    jb noia32e             ; It is less, there is no long mode.
    ret
    
noia32e:

    mov ax,flatdata
    mov ds,ax
    
    mov esi,0x000b8000
    
    mov ebx,NO_IA32E_ERROR
    
    mov ecx,76
    
Print_no_IA32E_Error:
    
    mov byte al,[ebx]           ;read NO_CPUID_ERROR
    add ebx,1
    
    mov byte [esi],al           ;write 0xb8000
    add esi,2
                     
    loop Print_no_IA32E_Error
    
    hlt

[bits 64]

bsp_long_mode:
    
    lgdt [GDT_PROP_64]
    
    mov rax,flatdata
    mov ds,rax
    mov ss,rax
    mov sp,0x00006000
    
    call Load_Kernel
    
    hlt
    
Load_Kernel:
    
    mov rsi,0x00000000
    
    mov rbx,loading_kernel_Message
    
    mov rcx,21
    
Print_Loading_Kernel_Message:
    
    mov byte al,[rbx]           ;read message
    
    add rbx,1
    
    mov byte [rsi],al           ;write 0x000b8000
    add rsi,2
                     
    loop Print_Loading_Kernel_Message

    ret
    
loading_kernel_Message:

    db 'Loading Mio Kernel...'
    
[bits 64]

restart:
    
    mov dx,0xcf9
    mov al,0xe
    out dx,al

这是我的完整代码,运行结果如下:

Kn’chmf?Lhn?Jdqmdk———

文本输出的 ASCII 代码比应有的低 1,因此在字母表中比应有的早 1 个字母。应为“正在加载...”

在此处输入图片描述

assembly
  • 1 个回答
  • 90 Views
Martin Hope
M.E.
Asked: 2025-03-09 21:07:51 +0800 CST

真实模式下的 Hello World

  • 6

我正在尝试在实模式下编写一个将在 QEMU 中运行的示例“Hello World”。主机是运行 FreeBSD 14 的 64 位英特尔。

我尝试了以下方法:

这是boot.asm文件:

format binary
org 0x7C00      ; Bootloader loaded at 0x7C00

start:
    ; Set up segment registers
    mov ax, cs
    mov ds, ax
    mov es, ax

    ; Set up stack
    mov ax, 0x0000
    mov ss, ax
    mov sp, 0x7C00

    ; Print message using BIOS interrupt
    mov si, msg
print_loop:
    lodsb               ; Load next character
    test al, al
    jz halt             ; Jump if null terminator
    mov ah, 0x0E        ; BIOS teletype function
    int 0x10            ; Call BIOS
    jmp print_loop

halt:
    cli                 ; Disable interrupts
    hlt                 ; Halt processor

msg db "Hello, World!", 0

times 510 - ($-$$) db 0 ; Pad to 510 bytes
dw 0xAA55               ; Boot signature

这是 makefile:

# Makefile for FreeBSD bootloader example

ASM = fasm
QEMU = qemu-system-i386
TARGET = boot.bin
SOURCE = boot.asm

all: $(TARGET)

$(TARGET): $(SOURCE)
        $(ASM) $(SOURCE) $(TARGET)

run: $(TARGET)
        $(QEMU) -fda boot.bin -serial stdio -display none

clean:
        rm -f $(TARGET)

这是我组装文件并通过 qemu 运行后得到的结果:

$ make
fasm boot.asm boot.bin
flat assembler  version 1.73.32  (16384 kilobytes memory)
2 passes, 512 bytes.

$ make run
qemu-system-i386 -fda boot.bin -serial stdio -display none
WARNING: Image format was not specified for 'boot.bin' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.

一些问题:

  1. 我希望 -serial stdio 捕获示例引导加载程序显示的消息的输出,但没有显示任何消息。
  2. 如何指定 qemu 的文件格式以便不再显示警告。
assembly
  • 1 个回答
  • 34 Views
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

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