汇编 从文件读取字符并在屏幕显示的问题

时间:2023-01-14 00:16:13
assume cs:codeseg,ds:datas,ss:stk

stk segment stack
  db 128 dup(0)
stk ends

datas segment
  tgtdata db 256 dup('$')
  filename db 'd:/asm.txt',0
datas ends

codeseg segment
start:
;设置栈段
mov ax,stk
mov ss,ax
mov sp,128

call ReadFile
 
        mov ax,seg tgtdata
mov ds,ax
mov si,offset tgtdata
mov bl,01000001b
mov dh,5
mov dl,8
call DisplayStringInDefinePos

mov ax,4c00h
int 21h

ReadFile:
push ax
push bx
push cx
push ds
; 打开文件
mov cx,0 ;文件属性
mov dx,seg filename
mov ds,dx
mov dx,offset filename
mov ah,3dh ;4d号功能,打开文件
mov al,0 ;0-读,1-写,3-读/写
int 21h  ;ax- 返回的文件代号
mov bx,ax ;文件代号放在 bx 中

        mov dx,seg tgtdata
mov ds,dx
mov dx,offset tgtdata
mov cx,1  ;要读取的数据长度,字节数
;mov bx,ax   ;文件代号,已放在bx
mov ah,3fh   ;读文件
int 21h
                
;关闭文件
;mov bx,ax   ;文件代号,已放在bx
mov ah,3eh   ;关闭
int 21h
pop ds
pop cx
pop bx
pop ax
ret
 
DisplayStringInDefinePos: 
pushf
push ax
push bx
push cx
push dx
push si
push di
push es

;根据要输出的位置,计算目标区在内存中的地址,放到di中
mov al,160
mul dh
mov di,ax
        mov al,2
        mul dl         ;乘法 ax = dl x 2,结果在ax中
        add di,ax       ;计算输出的位置:di = dh*160 + dl*2

        mov ax,0B800h   ;显存第0页起始地址
        mov es,ax       ;设定显存的段

        ;从ds:[si]依次取字符,以cl为中转
        DSIDF0: mov bh,[si]
        cmp bh,'$'
        je DSIDF1 ;如果字符为$,则不输出
        mov es:[di],bh;在dh行,dl列,输出字符
        mov es:[di+1],bl ;用bl设定颜色
        add di,2
        inc si
        cmp bh,'$'
        jne DSIDF0
    
        DSIDF1: 
        pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
        ret

codeseg ends
end start


运行后光标闪动要求我输入字符,然后显示得字符是我输入的字符,而不是我指定文件中的。各位帮忙看看怎么回事。。

3 个解决方案

#1


你 D: 根目录下有那个 asm.txt 文件吗,或者是被其它程序独占打开着?另外,dos 下习惯用反斜杠做分隔符吧。

#2


甚至DOS下文件名都用大写英文字母。

#3


小写文件名不影响使用,虽然DOS7之前的版本文件系统一律使用大写存储文件名。

#1


你 D: 根目录下有那个 asm.txt 文件吗,或者是被其它程序独占打开着?另外,dos 下习惯用反斜杠做分隔符吧。

#2


甚至DOS下文件名都用大写英文字母。

#3


小写文件名不影响使用,虽然DOS7之前的版本文件系统一律使用大写存储文件名。