assembly - ASM x86 推送和弹出

标签 assembly x86 tasm

这应该将用户给出的字符串与文本文件的每一行进行比较

如果等于则必须打印该行

<小时/>

但是即使提供了正确的字符串,程序也不会打印任何内容

我可能在使用 pushpop 指令时做错了

.model small
.stack  100h

.data
            filename          db 255 dup(0)
            text              db 255 dup(0)
            char              db ?

            text1             db 0dh, 0ah, 'Enter a string to search for: $'
            text2             db 0dh, 0ah, 'Enter a filename             : $' 

            string            db 255 dup(0)

            filehandle        dw ?

.code
            newline macro    ;NEW LINE
                             ;
            mov dl, 10       ;
            mov ah, 02h      ;
            int 21h          ;
                             ;
            mov dl, 13       ;
            mov ah, 02h      ;                     ;
            int 21h          ;
            endm             ;NEW LINE
main:

            mov ax, @data
            mov ds, ax

            mov ah, 09h
            lea dx, text1    ;'Enter a string to search for: $'
            int 21h 

            lea si, string
            mov ah, 01h      ;read character

string_input:

            int 21h

            cmp al, 0dh      ;end of string
            je zero_terminator2

            mov [si], al
            inc si

            jmp string_input

zero_terminator2:

            mov byte ptr [si], 0

            mov ah, 09h
            lea dx, text2
            int 21h 

            lea si, filename
            mov ah, 01h      ;read character

char_input:

            int 21h

            cmp al, 0dh      ;end of string
            je zero_terminator

            mov [si], al
            inc si

            jmp char_input

zero_terminator:

            mov byte ptr [si], 0

open_file:

            lea dx, filename
            mov al, 0
            mov ah, 3Dh      ;open file
            int 21h

            mov filehandle, ax

            lea si, text

read_line:

            mov ah, 3Fh      ;read file
            mov bx, filehandle
            lea dx, char
            mov cx, 1
            int 21h

            cmp ax, 0       ;EOF
            je EO_file

            mov al, char

            cmp al, 0ah     ; line feed
            je compare      ; compare line with string given by user

            mov [si], al
            inc si

            jmp read_line

EO_file:

            push dx         ;save dx for later use
            push cx         ;
            push si         ;

            xor dx, dx
            xor si, si
            xor di, di

            lea si, text
            lea di, string 

        loop_cmp_EOF:

            mov al, [si]    ;Get the next byte from text
            mov bl, [di]    ;Get the next byte from string

            cmp al, bl      ;Compare bytes
            jne end_it      ;end of program if not equal

            cmp al, 0       ;End of string. text=string
            je last_print   ;Print that line from text  

            inc si
            inc di 

            jmp loop_cmp_EOF  

        last_print:

            pop dx           
            pop cx
            pop si   

            newline

            lea dx, text    ;DX=offset(address) of text
            mov ah, 40h     ;print
            mov cx, si      ;CX = # characters. Move pointer to last char to it
            sub cx, dx      ;Subtract the offset of text (in DX) from CX
                            ;To get the actual number of chars in the buffer
            mov bx, 1
            int 21h  

       end_it:

            mov ah, 4ch
            int 21h

LF_print:    

            pop dx           
            pop cx
            pop si

            newline         ;Macro

            lea dx, text    ;DX=offset(address) of text
            mov ah, 40h     ;print
            mov cx, si      ;CX = # characters. Move pointer to last char to it
            sub cx, dx      ;Subtract the offset of text (in DX) from CX
                            ;To get the actual number of chars in the buffer                
            mov bx, 1
            int 21h 

            mov si, dx      ;Start from beginning of buffer 
                            ;(DX=beginning of text buffer)
            jmp read_line


       compare:

            push dx         ;save dx for later use
            push cx         ;
            push si         ;

            xor dx, dx
            xor si, si
            xor di, di

            lea si, text
            lea di, string 

       loop_cmp:

            mov al, [si]    ;Get the next byte from text
            mov bl, [di]    ;Get the next byte from string

            cmp al, bl      ;Compare bytes
            jne read_line   ;Do not print. Take another line from text

            cmp al, 0       ;End of string. text=string
            je LF_print     ;Print that line from text 

            inc si
            inc di 

            jmp loop_cmp

end main

最佳答案

一些问题。

  • 您必须以相反的顺序弹出寄存器。

    push dx         ;save dx for later use
    push cx         ;
    push si         ;
    ...
    pop  si           
    pop  cx
    pop  dx
    
  • loop_cmp中,你不能直接跳回read_line,因为你有3个单词压入堆栈,永远不会弹出!

    loop_cmp:
     mov al, [si]    ;Get the next byte from text
     mov bl, [di]    ;Get the next byte from string
     cmp al, bl      ;Compare bytes
     jne read_line   ;Do not print. Take another line from text
    
  • loop_cmp 中,您与零进行比较,但您将行尾定义为换行符 (=10)。这不一致!

     cmp al, 0       ;End of string. text=string
     je LF_print     ;Print that line from text
    

关于assembly - ASM x86 推送和弹出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33647538/

相关文章:

c - 分支预测器条目在程序完成后失效?

assembly - (本地)标签如何在其自己的段(TASM 8086)之外结束?

assembly - 在 DOS 中获取没有回显的键盘输入

assembly - emacs:如何关闭自动缩进?

linux - 带有 cx 寄存器的 NASM 汇编器无限循环

assembly - 计算汇编 x86 中的 LCM

winapi - 我的 objdump 中的这一行是什么?

c - "Trace/breakpoint trap (core dumped)"在汇编中除以负值时出错

assembly - 为什么我的汇编输出位于字母位置? (1+1=b)

c++ - 发布安全、宽松的内存模型和 memcpy