我想从命令行中读取文件的名称。该名称存储在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
答案 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.