如何保护 x86 程序集中的多个声明?

How to guard multiple declaration in x86 assembly?

我已经编写了 x86 汇编代码来打印字符串并以十六进制格式打印寄存器的值。我创建了两个单独的 asm 文件,print_string.asm 用于打印字符串,print_hex.asm 用于打印十六进制值。我已将这些文件包含在我的 main.asm 文件中。现在的问题是 print_hex.asm 还包括 print_string.asm 用于打印字符串。所以汇编程序显示 symbol redefined 错误!我怎么解决这个问题?我正在使用 NASM 作为汇编器。

这是我的汇编代码:

main.asm

mov ax, 0x7c0
mov ds, ax
mov bx, STRING
call PRINT_STRING

mov dx, 0x4f3e
call PRINT_HEX

jmp $

%include "printstring.asm"
%include "printhex.asm"

STRING:
    db 'Hello World', 0

times 510-($-$$) db 0
dw 0xaa55

print_string.asm

PRINT_STRING:
    pusha
    mov ah, 0x0e

    PLOOP:
        cmp byte [bx], 0
        je POUT
        mov al, [bx]
        int 0x10
        add bx, 1
        jmp PLOOP

    POUT:
        popa
        ret

printhex.asm

; This routine will print value of dx register
; into hex

; Hex Template Manipulation
mov bx, HEX_TEMP
add bx, 5

HLOOP:
    cmp byte [bx], 'x'
    je HOUT
    mov ax, 0x000f
    and ax, dx
    cmp ax, 0x09
    jg HCHAR
    add ax, 0x30

HCOMM:
    mov byte [bx], al
    shr dx, 4
    sub bx, 1
    jmp HLOOP

HCHAR:
    sub ax, 0x0a
    add ax, 0x61
    jmp HCOMM

HOUT:

mov bx, HEX_TEMP
call PRINT_STRING

%include "printstring.asm"

HEX_TEMP:
    db '0x0000', 0

当我尝试编译它时显示以下错误:

printstring.asm:1: error: symbol `PRINT_STRING' redefined
printstring.asm:5: error: symbol `PLOOP' redefined
printstring.asm:13: error: symbol `POUT' redefined

我猜你正在使用 NASM?如果是这样,您可以采用与在 C 头文件中使用的方法完全相同的方法,并将包含的 asm 文件包装在 %ifndef - %endif 块中。

%ifndef PRINT_STRING_ASM
    %define PRINT_STRING_ASM
    ; body of print_string.asm 
%endif

如果多次包含文件,则 PRINT_STRING_ASM 宏将在第二次定义时被定义,文件的内容将被跳过。

对于给定的 main.asm,只需从 printhex.asm 中删除 %include "printstring.asm" 它已经包含在 main.asm 中。

对于更通用的解决方案,删除所有 %include 语句,使每个函数分别成为 global/extern 和 assemble 它们。然后,link他们在一起。

虽然可以使用 %ifndef/%define/%endif 锁 [类似于 C 中用于 .h 文件的锁],但不建议这样做,因为您在 .asm 中有代码文件,并可能生成函数的多个副本作为私有函数