x86 ASM - 逐行阅读

时间:2015-11-10 20:52:02

标签: assembly x86 tasm

好的,我想做的只是从文本中逐行阅读然后输出它。

我做的事情:

  • 读取单个字符,添加到字符串
  • 搜寻LF
  • 输出字符串
  • 重新做一遍直到EOF

问题:

  • 不知道如何计算cx为40h中断而它忙于3Fh(尝试制作一些新的变量,但最终出现了一堆错误)
  • 某种奇怪的结果 - 很少有空行和最后一行
  

.txt示例

     
    some
    random

    text
  
    .model small

    .stack  100h 

    .data 
            filename    db 255 dup(0)   
            text        db 255 dup(0)
            char        db ?
            line        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   

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

    char_input:

            int 21h         

            cmp al, 0dh      ;enter     
            je zero_terminator

            mov [si], al    
            inc si

            jmp char_input  

    zero_terminator:

            mov [si], 0 

    open_file:

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

            mov filehandle, ax

            lea si, text   

            newline

    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 LF  

            mov [si], al
            inc si      

            jmp read_line:

    EO_file:

            lea dx, text
            mov ah, 40h     ;print 
            mov cx, 255
            mov bx, 1       
            int 21h

            mov ah, 4ch     
            int 21h 

    LF:       
            lea dx, text
            mov ah, 40h     ;print
            mov cx, 255
            mov bx, 1

            int 21h

            inc si
            jmp read_line

     end main  

1 个答案:

答案 0 :(得分:3)

这是为了让您前进,而不是解决代码中的所有错误:

你有:

var myArray = ["Arthur Philadelpho", "arthurphiladelpho"];

function cutName (myArray){return myArray.split(" "); }

var myData = {**fullname:myArray[0]**, skype:myArray[1], github:null};

想法是将0字节移动到 SI 指向的位置。 TASM 并不了解您想要将单个字节移动到[SI],因此应明确告知它是您的意图:

zero_terminator:
        mov [si], 0 

你在这一行有一个拼写错误:

        mov byte ptr [si], 0 

应该是:

        jmp read_line:

您的代码的主要问题是,当打印出读入 jmp read_line 字符数组的字符时,您需要指定要在 CX 中打印的字符数。您可以使用以下代码指定255:

text

由于 SI 包含指向最后一个字符读取的指针,因此您可以从 SI 中减去 text 的地址(偏移量)以获取缓冲区中的字符数。所以上面的内容可以改为:

LF:
        lea dx, text
        mov ah, 40h     ;print
        mov cx, 255

打印出一行 SI 并返回阅读字符。由于您已打印出该行,您也可以从文本缓冲区的开头重新启动,方法是将 SI 重置为开头:

LF:
        lea dx, 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

或者您可以只移动 DX ,其中包含 text 的偏移量,并将 SI 设置为:

这与您最初在读取数据时设置的方式相同。

您拥有的 EOF 代码有一个类似的问题,即需要将缓冲区中的字节数放在 ECX 中。所以这段代码:

        mov si, dx ; start from beginning of buffer (DX=beginning of text buffer)

可以更改为:

EO_file:

        lea dx, text
        mov ah, 40h     ;print
        mov cx, 255
        mov bx, 1
        int 21h

通过所有这些更改,您将获得如下程序:

LF:
        lea dx, 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