2016-04-23 8 views
3

Ich habe x86-Assembler-Code geschrieben, um eine Zeichenfolge zu drucken und den Wert eines Registers im hexadezimalen Format zu drucken. Ich habe zwei separate asm-Dateien erstellt, print_string.asm zum Drucken einer Zeichenfolge und print_hex.asm zum Drucken eines Hexadezimalwerts. Ich habe diese Dateien in meine main.asm Datei aufgenommen. Jetzt ist das Problem print_hex.asm enthält auch print_string.asm zum Drucken einer Zeichenfolge. So zeigt der Assembler symbol redefined Fehler an! Wie kann ich dieses Problem lösen? Ich benutze NASM als Assembler.Wie schützt man mehrere Deklarationen in der x86-Assembly?

Hier ist meine Assembler-Code:

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 

Wenn ich versuche, seine Vorführung folgende Fehler zu kompilieren:

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

Antwort

2

Ich vermute, dass Sie NASM verwenden? Wenn dies der Fall ist, können Sie den gleichen Ansatz wie in einer C-Header-Datei verwenden und die enthaltene asm-Datei in einen %ifndef - %endif Block einbinden.

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

Wenn die Datei mehr als einmal enthalten ist, dann wird das PRINT_STRING_ASM Makro definiert worden sein wird zum zweiten Mal durch, und der Inhalt der Datei übersprungen.

2

Für Ihre gegebene main.asm, entfernen Sie einfach die %include "printstring.asm" von printhex.asm Es ist bereits in main.asm enthalten.

Für eine allgemeinere Lösung, entfernen Sie alle %include Anweisungen, machen Sie jede Funktion global/extern und montieren Sie sie separat. Verknüpfen Sie sie dann miteinander.

Während ein %ifndef/%define/%endif Lock [ähnlich dem, was für .h Dateien in C verwendet wird] verwendet werden kann, ist es nicht ratsam, weil Sie Code in den .asm Dateien haben und möglicherweise mehrere Kopien von Funktionen als private Funktionen

erzeugen