2016-04-02 13 views
0

Ich schrieb eine Funktion entwickelt, um eine 4 Buchstabenfolge gegen die ersten vier Buchstaben in einem Puffer vergleichen:Vergleicht man Strings in 8086 real-Modus

is_cmd: 
           ; bx is the string address argument 
    push bx      ; Push bx to stack 
    mov cx, [bx]    ; and also move into cx 

    mov bx, BUFFER    ; Reset BUFFER_INDEX 
    mov [BUFFER_INDEX], bx  ; so it points to first 2 characters 

    mov bx, [BUFFER_INDEX] 
    cmp cx, [bx]    ; Compare 
    jne is_cmd_no    ; Jump if not equal 

    pop bx      ; Retrive bx from stack 
    inc bx      ; Move pointer to next 2 characters 
    mov cx, [bx]    ; Move to cx 

    mov bx, [BUFFER_INDEX]  ; Move BUFFER_INDEX into bx 
    inc bx      ; and move to next 2 characters 

    cmp cx, [bx]    ; Compare 
    jne is_cmd_no    ; Jump if not equal 
    jmp is_cmd_yes    ; Jump if equal both times 

is_cmd_no: 
    mov ax, 1     ; Set ax to 1 so jz will not jump 
    ret 

is_cmd_yes: 
    mov ax, 0     ; Set ax to 0 so jz will jump 
    ret 

Hier ist ein Beispiel dafür Nutzung ist:

mov bx, REBOOT_CMD 
call is_cmd 
or ax, ax 
jz reboot_cmd 

Und hier sind alle Variablen:

REBOOT_CMD: 
    db "rset",0 

BUFFER_INDEX: 
    dw BUFFER 

BUFFER: 
    times 80 db 0 
BUFFER_END: 

jedoch, wenn die Zeichenfolge nicht gleich ist es den Emulator verursacht (B OCHS) zu hängen. Warum?

+0

Schauen Sie auf Ihre Pushs und Pops. Nach dem Vergleich hast du gedrängt, aber nicht geplatzt. (Unrelated) 'inc bx' lässt es nicht auf den nächsten Satz von 2 Zeichen zeigen. Sie brauchen 'add bx, 2' hier. – usr2564301

+0

Es gibt keine Notwendigkeit, [buffer_index] zu verwenden, warum vergleichen Sie [bx] nicht einfach mit [Buffer] und [bx + 2] mit [buffer + 2]? – Tommylee2k

Antwort

1

Verwenden Sie AXE zum Vergleichen, es ist sowieso geändert; es ist nicht nötig, irgendetwas anderes zu überlisten; und lassen Sie die CPU die "Zeiger Berechnung" tun, können Sie lesen aus [BX + 2], gibt es keine Notwendigkeit zu ändern, es

mov bx, REBOOT_CMD 
call is_cmd 
or ax, ax 
jz reboot_cmd 

is_cmd: 
    mov ax, [bx] 
    cmp ax, [BUFFER]   ; [buffer] with [bx] 
    jne is_cmd_no 
    mov ax, [bx+2] 
    cmp ax, [BUFFER+2]  ; [buffer+2] with [bx+2] 
    jne is_cmd_no 
    mov ax, 1     ; is_cmd_yes 
    ret 
is_cmd_no: 
    xor ax, ax 
    ret 

oder noch besser, Inline es in die Use-Case

is_reboot: 
    mov ax, [REBOOT_CMD] 
    cmp ax, [BUFFER]   ; [buffer] with "rs" 
    jne no_reboot 
    mov ax, [REBOOT_CMD+2] 
    cmp ax, [BUFFER+2]  ; [buffer+2] with "et" 
    jz reboot_cmd 
no_reboot: 

Hinweis: Die 2 Zweige unterscheiden sich, erstens ist ein "jne", zweitens ein "jz" zum Neustart Fall. es ist wie ein "UND" in C, wo der 2. Teil des Ausdrucks nur ausgewertet wird, wenn der erste TRUE als Ergebnis hatte

wenn Sie sich obfuscting fühlen, wenn auch der "BUFFER db" rset ", 0" ist obsolet, man könnte [BUFFER] mit "rs" vergleichen (was "s" + 0x100 * "r" = 0x7372 ist) und [BUFFER + 2] mit "et" (= "e" + 0x100 * "t" = 0x7465):

is_reboot: 
    cmp word ptr [BUFFER],0x7372   ; [buffer] with "rs" 
    jne no_reboot 
    cmp word ptr [BUFFER+2],0x7465  ; [buffer+2] with "et" 
    jz reboot_cmd 
no_reboot: 
+0

Danke, das hat perfekt funktioniert! –

+0

Verwenden Sie nicht 'oder ax, ax' als Idiom zum Setzen von Flags basierend auf dem Inhalt eines Registers (auch als Vergleich mit Null). "Test Axt, Axt" hat einige signifikante Vorteile, einschließlich Makro-Fusing mit Verzweigungen zu dekodieren und schneller zu laufen. @EdwardAtkinson: Wenn diese Antwort Ihr Problem gelöst hat, vergessen Sie nicht, das Häkchen unter den Auf/Ab-Tasten zu setzen, um es zu bestätigen. –

+0

Auch in einigen Assembler (einschließlich NASM und MASM) können Sie 'cmp ..., 'rs'' und' cmp ...,' et'' schreiben, also ist es nicht wirklich so verschleiert. Gute Idee zum Speichern der Zeichenfolge als Sofortdaten. –

0

Ein Vorschlag zur Überprüfung, ob es ein Befehl ist. Beachten Sie, dass ich einem Match einen 'TRUE' Wert von 1 und einem nicht übereinstimmenden Ergebnis einen FALSE Wert von 0 zugewiesen habe. Wenn Sie es wirklich anders mögen, tauschen Sie einfach mov ax,1 und xor ax, ax im folgenden Code aus. Beachten Sie auch, dass die Verwendung von BUFFER_INDEX nicht erforderlich ist.

is_cmd: 
    mov cx, [bx] 
    mov dx, [bx+2] 
    lea bx, BUFFER   ; Reset BUFFER_INDEX to effective address of BUFFER 
    ; -- mov [BUFFER_INDEX], bx ; so it points to first 2 characters 
    ; -- mov bx, [BUFFER_INDEX] ; is redundant, because BX is already equal to BUFFER_INDEX 
    cmp cx, [bx]    ; compare first two chars 
    je first_two_match 
    jmp is_cmd_no 
first_two_match: 
    cmp dx, [bx+2]   ; compare the second two chars 
    jne is_cmd_no 
    mov ax, 1    ; is_cmd_yes 
    ret 
is_cmd_no: 
    xor ax, ax 
    ret 
Verwandte Themen