如何从ASM命令行中收到的文件中读取内容

时间:2016-06-01 15:55:13

标签: assembly tasm

我想从命令行中读取文件的名称。该名称存储在var4中,然后我从我收到的名称的文件中读取并将文本存储在var2中。然后我想显示文件中的内容。当我直接给出名称时,不使用命令行(将名称存储在var1中,然后打开具有该名称的文件),它可以正常工作。但是当我使用我在命令行中收到的名称时,即使它们具有相同的名称,它也不起作用。我怎样才能解决这个问题。 我正在使用TASM

datos segment
var3 db 128 dup(0)
var2 db 128 dup(0)
handle dw 0
var1 db "c:\xxx.txt",0
var4 db 10 dup(0)

datos ends

pila segment stack "stack"
dw 256 dup(?)
pila ends


codigo segment
assume cs:codigo, ds:datos, ss:pila

inicio:
     mov ax,ds
     mov es,ax

     mov ax, datos
     mov ds,ax

     mov ax,pila
     mov ss,ax



     mov si, 80h
     mov cl, byte ptr es:[si]
     xor ch, ch

     xor di, di
     inc si
ciclo: inc si
      mov al, byte ptr es:[si]
      mov byte ptr var4[di], al
      inc di

      loop ciclo
      mov byte ptr var4[di],0


      mov ah,3dh
      lea dx,var4
      mov al,00h
      int 21h
      mov word ptr handle ,ax

      inc di
      mov byte ptr var4[di],0dh
      inc di
      mov byte ptr var4[di],0ah

      mov ah,3fh
      mov bx, handle
      mov cx,100h
      lea dx,var2
      int 21h 

      xor si,si
      xor di,di
      mov cl,ds:[si]

    ciclo2: 
      mov al, byte ptr var2[si]

      mov byte ptr var3[di], al
     inc si
     inc di
    loop ciclo2
      mov byte ptr var3[di],'$'


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

     fin:
     mov ax,4C00H
     int 21h
 codigo ends

 end inicio

2 个答案:

答案 0 :(得分:1)

mov si, 80h
 mov cl, byte ptr es:[si]
 xor ch, ch
 xor di, di
 inc si                       <<< Remove this instruction!
ciclo: inc si
 mov al, byte ptr es:[si]
 mov byte ptr var4[di], al
 inc di
 loop ciclo
 mov byte ptr var4[di],0

提取文件规范的代码是错误的。使用命令行第一个字节的字节数很好,但由于您在SI中对索引使用预递增,因此不应使用单独的指令跳过字节计数。使用当前代码,您忽略了重要的第一个字符,并在filespec中包含终止回车符。两者都打开文件失败。

var1 db "c:\xxx.txt",0
var4 db 10 dup(0)

如果在命令行中你写了&#34; c:\ xxx.txt&#34;然后你最好放大 var4 的缓冲区,因为10个字节太少了。添加空字节,添加回车符,然后添加换行符。顺便说一句:在空字节之后添加 CRLF的用途是什么?虽然在 ciclo2 循环结束时和添加$ -sign之前有意义。

var2 db 128 dup(0)
...
mov ah,3fh
mov bx, handle
mov cx,100h
lea dx,var2
int 21h 

您阅读的内容超过 var2 的缓冲区可以容纳的数据!

xor si,si
xor di,di
mov cl,ds:[si]

您对DS中的地址零的期望是什么? 为什么不将CH初始化为零? (loop需要整个CX)

ciclo2: 
mov al, byte ptr var2[si]
mov byte ptr var3[di], al
inc si
inc di
loop ciclo2

由于先前使用mov cx,100h并且只设置了CL寄存器,因此该循环将执行太多次!

答案 1 :(得分:0)

首先是一些理论(正如Peter Cordes所说):PSP(程序段前缀)是存储在内存中的数据结构,用于保存有关当前程序的信息。从PSP的偏移80h开始,我们找到了DTA,程序参数在那里。 DTA的第一个字节是它的长度(参数字符串的长度)。

为了获得参数,可以访问PSP,然后跳转到偏移80h,如下所示:

ngModel

但还有另一项服务直接获得DTA(Angular docs):

mov ah, 62h   ;SERVICE TO GET PSP SEGMENT.
int 21h       ;PSP SEGMENT RETURNS IN BX.
mov es, bx    ;ES POINTS TO PSP SEGMENT.
mov si, 80h   ;NOW ES:SI POINTS TO DTA.

要获取程序参数,我们需要记住,从命令行开始,参数以ENTER键(char 13)结束,因此,从DTA的偏移量1开始,我们读取字符直到找到13。也可以使用第一个字节(长度),但这将包括char 13作为文件名的一部分,我们不希望这样。

现在对箭头指向的程序所做的更改(“&lt; ======”):

mov ah, 2fh   ;SERVICE TO GET DTA ADDRESS.
int 21h       ;RETURNS ES:BX POINTING TO DTA.