【问题标题】:Assembly jmp not jumping汇编 jmp 不跳转
【发布时间】:2019-04-18 19:34:14
【问题描述】:

问题是即使dlbl 相等,它也不会跳转到doi。有谁知道为什么?

assume cs:code,ds:data
data segment
sir1 db "abc"
l1 equ $-sir1
sir2 db "a"
l2 equ $-sir2
bunbun db "Este!$"
nu db "NU este!$"
iesire db "Apasa Enter!$"

data ends

code segment
start:
    mov ax,data
    mov ds,ax

    mov bp,offset sir1
    mov si,offset sir2
    dec bp
    push bp
    push si
    mov ah,l1
    mov bh,l2

unu:
    pop si
    pop bp
    inc bp
    dec ah
    mov dl,sir1[bp]
    mov bl,sir2[si]
    push bp
    push si
    cmp dl,bl
    je doi
    cmp ah,0
    je nu_bun
    jmp unu

doi:
    inc si
    inc bp
    dec ah
    mov dl,sir1[bp]
    mov bl,sir2[si]
    cmp dl,bl
    jne unu
    cmp bh,0
    je bun
    jmp doi

bun:
    mov dx,offset bunbun
    mov ah,09h
    int 21h
    mov ah, 09h
    mov dx,offset iesire
    int 21h
    mov ah, 0ah
    int 21h
    mov ax,4c00h
    int 21h

nu_bun:
    mov dx,offset nu
    mov ah,09h
    int 21h
    mov ah, 09h
    mov dx,offset iesire
    int 21h
    mov ah, 0ah
    int 21h
    mov ax,4c00h
    int 21h

code ends
end start

【问题讨论】:

  • 您如何确定dlbl 相等? [bp] 默认为 ss:[bp]... 这不是您的字符串所在的位置。试试di,而不是那里的bp

标签: assembly x86 dos x86-16


【解决方案1】:

这比较隐式长度以 0 结尾的字符串。 (与问题中的字符串不同,这些字符串要么是显式长度(l1 equ $-sir1,但没有特殊字节标记结尾),要么有 $ 终止符。)

它还假设 ES = DS,或者第二个字符串由 ES:BP 指向。 (问题是其中一个使用[BP],这可能是一个错误,除非您使用 DS = SS 的“微小”代码模型。)

doi:
   ; cld             ; assume DF=0
    xchg di, bp
    mov cx, ax
    xor ax, ax

cmp_next:            ; do{
    lodsb              ; AL = [si]        ; si++
    scasb              ; cmp al, [es:di]  ; di++
    jnz not_equal
    test  al, al
    jnz   cmp_next   ; }while(al!=0);
   ; else fall through if we reached the end without finding a difference
do_equal:
    xchg di, bp
    mov ax, cx
    jmp somewhere_togo_when_equal

not_equal:
    xchg di, bp
    mov ax, cx
    jmp somewhere_togo_when_not_equal

【讨论】:

  • dec si / cmpsb 有什么意义?为什么不使用scasb?此外,or al,al 在大多数 CPU 上都比 test al,al 差。另外,像普通人一样使用jnz cmp_next,而不是jz 而不是jmp。这是一个非常糟糕的例子,并没有解释这个问题实际上有什么问题。 (这太乱了......)
  • @PeterCordes 我倾向于让代码自己解释,所以形式就是这样。我真的不知道当字节相等或不相等时 OP 想做什么,所以我让两个分支都“可见”。这可能不是编码的好习惯,但我试图减少对指令集和隐含标志更改的了解。
  • 您可以在直通路径上放置标签(或注释),但仍然可以编写一个简单的循环,并在底部使用标准test/jnz。如果您想让对 ISA 知识有限的人更容易理解,请使用 cmp al, 0 / jne。 (在这种特定情况下,对于al,它的代码大小仍然与test al,al 相同)。不过,使用or 设置标志,并使用复杂的指令如lodsbcmpsb 与保持简单相反。
  • @PeterCordes 对于答案被接受了,这似乎有助于 OP 在代码中解决他/她的问题。我会考虑保持原样,但是,请随时修改:)
猜你喜欢
  • 1970-01-01
  • 2019-04-17
  • 2013-05-09
  • 1970-01-01
  • 2016-11-01
  • 2015-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多