2016-04-02 53 views
0

比較字符串我寫設計成4字母串對前4個字母在緩衝區比較的功能:在8086實模式

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 

下面是一個例子的它的用法:

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

這裏是所有的變量:

REBOOT_CMD: 
    db "rset",0 

BUFFER_INDEX: 
    dw BUFFER 

BUFFER: 
    times 80 db 0 
BUFFER_END: 

但是當字符串不等於它會導致仿真器(B OCHS)掛起。爲什麼?

+0

看看你的推動和砰砰聲。比較之後,你推動但沒有彈出。 (無關)'inc bx'不會使它指向下一組2個字符。你需要在這裏添加bx,2。 – usr2564301

+0

沒有必要使用[buffer_index],爲什麼不簡單地用[buffer + 2]與[Buffer]和[bx + 2]進行比較[bx]? – Tommylee2k

回答

1

使用AX進行比較,反正它改變了;沒有必要破壞別的東西;並讓CPU做「指針計算」,你可以從閱讀[BX + 2],就沒有必要去改變它

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 

,甚至更好,它內聯到用例

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: 

注意:2個分支不同,第一個是「jne」,第二個是「jz」到重啓的情況。它就像C中的「AND」,其中第二部分表達式僅被評估,如果第一部分的結果爲TRUE

如果您覺得如果即使「BUFFER db」rset「0」爲「obfuscting」過時的,你可以用「et」(=「e」+ 0x100 *「t」= 0x7465)將[BUFFER]與「rs」(它是「s」+ 0x100 *「r」= 0x7372)和[BUFFER + 2] ):

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

謝謝,這工作完美! –

+0

請勿使用'或ax,ax'作爲根據寄存器內容設置標誌的語言(又稱爲0)。 '測試ax,ax'具有一些顯着的優點,包括用分支進行宏融合來解碼和運行更快。 @EdwardAtkinson:如果此答案解決了您的問題,請不要忘記單擊向上/向下投票按鈕下方的複選標記以將其標記爲已接受。 –

+0

此外,在一些彙編器 (包括NASM和MASM)中,您可以編寫'cmp ...,'rs''和'cmp ...'等,所以它不是真的被混淆。將字符串存儲爲即時數據的好主意。 –

0

建議檢查它是否是命令。請注意一個事實,即我將'TRUE'值分配給了一個匹配項,將一個FALSE值分配給了一個不匹配的結果。如果你真的喜歡它,只需在下面的代碼中交換mov ax,1xor ax, ax。另請注意,使用BUFFER_INDEX不是必需的。

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