代码之家  ›  专栏  ›  技术社区  ›  the_endian

8086汇编程序始终打印相同的字符串

  •  1
  • the_endian  · 技术社区  · 7 年前

    我已经使用启用了fasm语法的emu8086编写了下面的程序。如您所见,程序应在第一次打印“溢出标志未设置”,然后在加法设置溢出标志后,再打印“溢出标志未设置”

    然而,事实并非如此。在任何情况下,程序都会打印“溢出标志集”。我已经完成了这段代码,o\u set位于地址0,o\u notset位于地址13h。 在调用int 21h with al 09h时,无论是将13h还是0h放入dx,它都会打印“溢出标志集” 我在这里很困惑,因为我实际上在数据段中将它们分配为两个独立的区域。请注意,跳转逻辑似乎工作正常, 问题是,无论dx中放置了什么,始终会打印相同的消息。事实上,如果我在dx中放入99,它仍然会打印“溢出标志集”

    format MZ   
    
    entry code_seg:start 
    
    stack 256
    
    
    segment data_seg
    o_set    db      "Overflow flag set $"
    o_notset    db      "Overflow flag not set $"
    
    segment code_seg
    start:      
    push bp
    mov bp, sp
    
    mov cl, 99
    jo of_flag_set
    
    push  o_notset
    call printf
    add sp, 2
    
    add cl, 98
    jo of_flag_set
    jmp endme
    
    of_flag_set:
    push o_notset
    call printf
    add sp, 2
    
    endme:
    mov sp, bp
    pop bp
    mov ah, 0h
    int 20h     
    
    ; Need to put offset to msg on stack prior to call. Stack cleaned up by callee
    printf:
    push bp
    mov bp, sp
    
    mov dx, [bp+4]              ;cant pop the retn addr into dx
    mov ah, 09h
    int 21h
    mov sp, bp
    pop bp
    ret
    
    1 回复  |  直到 5 年前
        1
  •  3
  •   Michael Petch    7 年前

    我已经评论了错误的地方,需要修复:

    format MZ   
    
    entry code_seg:start 
    
    stack 256
    
    
    segment data_seg
    ; Add carriage reurn and line feed to ut output on seprate lines.
    o_set       db      "Overflow flag set", 13, 10, "$"
    o_notset    db      "Overflow flag not set", 13, 10, "$"
    
    segment code_seg
    start:      
    push bp
    mov bp, sp
    mov ax, data_seg    ; We must set up the DS register by pointing
                        ;    at the segment with our data
    mov ds, ax
    
    test ax, ax         ; Make sure overflow flag is cleared
                        ;    Not guaranteed when our program starts
    
    mov cl, 99
    jo of_flag_set      ; You jumped to the wrong label when overflow was set
    
    push  o_notset
    call printf
    add sp, 2
    
    add cl, 98
    jo of_flag_set
    jmp endme
    
    of_flag_set:
    push o_set
    call printf
    add sp, 2
    
    endme:
    mov sp, bp
    pop bp
    mov ah, 0h
    int 20h     
    
    ; Need to put offset to msg on stack prior to call. Stack cleaned up by callee
    printf:
    push bp
    mov bp, sp
    
    mov dx, [bp+4]              ;cant pop the retn addr into dx
    mov ah, 09h
    int 21h
    mov sp, bp
    pop bp
    ret
    

    您的字符串没有正确打印(它们在屏幕上被移动),因为您没有设置 DS公司 (数据段)寄存器。创建DOS MZ(EXE)程序时,需要显式移动数据区域的段位置 data_seg DS公司 . 因为您没有这样做,所以字符串从错误的位置打印出来。

    我在字符串中添加了回车符和换行符,以便它们在单独的行上打印。

    您的代码不能依赖于在程序启动时清除溢出标志。你需要使用一个指令来清除它。 test ax, ax 如果你不介意改变其他标志的话,就可以了。

    你的一个 jo 当检测到溢出时,它指向错误标签的说明。

    推荐文章