我正在使用3Ch函数创建文件并使用40h函数保存字符(我读过它here)
我不明白如何在DS:DX
中添加阅读字符。
这是我的代码:
org 100h
bits 16
section .data
file DB 'file.txt',0
section .bss
file_handle resw 1
; CREATE FILE
section .text
mov DX, file
mov CX, 0000h
mov AH, 3Ch
int 21h
; START INPUT
INPUTSTART:
mov AH,01h
int 21h
; SAVE INPUT TO FILE
mov SI, file_handle
mov BX, [SI]
mov CX, 0001h
mov AH, 40h
int 21h
jmp INPUTSTART
mov AH,4Ch
int 21h
正如您所见,程序旨在循环工作并编写与用户类型一样多的字符。请帮助获取40h函数的文件句柄并将数据放入DS:DX
。
答案 0 :(得分:2)
基于代码的语法,我猜你正在使用NASM并尝试创建一个.COM程序。
.COM程序的代码从文件的最开始开始,并且文件没有任何划分为逻辑部分,因此您不能先放置数据部分(例如.data或.bss)而且它不会甚至定义这些部分也没有多大意义。
因此,您的代码应如下所示:
org 100h
bits 16
; code begins here
; then goes data
OR
org 100h
bits 16
jmp start
; here goes data
start:
; here goes the rest of code
接下来,函数3Ch返回AX
中的文件句柄。您可以使用此句柄对文件执行进一步操作(例如,读取,写入,关闭)。你的代码并没有在file_handle
中隐藏这个句柄,我猜测它是为了这个目的而准确定义的,并且通过用AX
覆盖mov AH,01h
的值来摧毁它。你需要解决这个问题。
在程序结束时,您必须使用功能3Eh关闭文件。如果不这样做,该文件可能最终只包含已写入其中的一部分数据,在重新启动PC之前该文件可能无法访问,您也可能无法打开(或创建)更多文件如果你积累了足够的未闭合文件句柄。所以,最后关闭文件。
至于保存文件中的字符,没有什么可以阻止你定义一个字节变量,比如key
,将AL
存储到其中,然后将key
的地址传递给函数40h ,例如:
...
mov AH,01h
int 21h
mov [key], AL
; SAVE INPUT TO FILE
mov BX, [file_handle]
mov DX, key
mov CX, 0001h
mov AH, 40h
int 21h
...
file_handle dw 0
key db 0
...
另外,不要忘记指定一些键来突破你现在在程序中的无限循环。
答案 1 :(得分:2)
实际上你没有将放在 ds:dx
中,而是使用ds:dx
来引用字符所在的内存地址或者存储的数据,在英特尔语法中它是[ds:dx]
(但dx
不能用于内存寻址)。
那么,你需要做什么:存储从键盘读取的值与DOS中断21h
/ ah = 01h
,在al
中返回到某个内存地址,然后引用该内存地址与ds:dx
。
在您的代码中,您根本不存储文件句柄,并在写入文件调用之前从变量file_handle
加载0,因为这是您初始化它的方式。然后你尝试从ds:0
读取文件句柄(因为si
等于0),这根本没有意义。您需要对文件句柄执行的操作就是存储它(在文件创建/截断后在ax
中返回值)并始终将其加载到后续int 21h
中引用相同文件的相关寄存器(写入文件,从文件中读取,关闭文件等。)。
所以,通过下面的修复,它应该工作(没有测试)。我还将函数调用参数组织为Ralf Brown中断列表使用的顺序,以便于理解。
.section data
file db 'file.txt',0
character_read db 0
...
% create file:
mov ah,3Ch % create or truncate a file
mov dx,file % ds:dx points to ASCIIZ filename
xor cx,cx % file attributes.
int 21h
mov [file_handle], ax % file handle must be stored in memory or in a register!
INPUTSTART:
mov ah,1 % read character from STDIN, with echo.
int 21h
mov [character_read], al % store the ASCII code to memory.
% unless you want to loop eternally, you can check the ASCII code and exit.
cmp al,20h % space.
je EXIT
mov ah,40h % write to file or device
mov bx,[file_handle] % file handle is just a number.
mov cx,1 % number of bytes to write.
mov dx,character_read
int 21h
jmp INPUTSTART
EXIT:
% here you can add some clean-up code, if needed.
mov ah,3Eh % close file.
mov bx,[file_handle] % here you need the file handle again.
int 21h
mov ah,4Ch
int 21h