我正在写我自己的中断,从一个文件到另一个文件传输100字节。(我的中断代码是0x 88)。
**中断的作用:**中断获取两个地址DS:DX -输入文件; ES:CX -输出文件,(在.com程序中,DS总是==到ES,所以地址将是DX和CX),其中包含文件名(ASCIIZ格式)。中断必须将第一个文件的前100个字节复制到第二个文件。如果少于100个字节,则用空格(ASCII代码0x 20)填充所需的100个字节。
**问题:**我不知道如何将数据从第一个文件传输到另一个文件,因为没有“section .data”(据我所知,我可能是错的,但我找不到任何有关这方面的信息)。
**我是怎么想的:**我想读取一个字节到寄存器,并将这个字节与0x 00比较(如果它不是文件的结尾)。然后将一个字节写入输出文件。如果这个字节是0x 00,这意味着到达了文件的结尾,所以我必须用空格填充(传输的100-字节)。
**问题:**如何读取寄存器中的一个字节(而不是缓冲区中的)?
**EDIT:**我试图将 section .data 添加到中断文件中。这是我目前得到的结果。我在最后添加空格(如果输入文件少于100字节)时遇到问题。
输入文件:
CCCCC
输出文件:
CCCCC mov di, .buffer
call procFPBCD2ASCIIZ
mov dx, di
call procPutStr
pop dx
输出文件有100个字节(根据需要),但它填充了其他内容。
%include 'yasmmac.inc'
;------------------------------------------------------------------------
org 100h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .text ; Code starts here
jmp Settings ;First launch
Old_I88:
dw 0, 0
procWrite:
jmp .next
.next:
mov [writingFile], cx
call procFOpenForReading
jnc .readingFileIsOpened
macPutString 'Error while opening reading file', '$'
exit
.readingFileIsOpened:
mov dx, buffer
mov cx, 100
call procFRead
jc .errorReading
call procFClose
cmp ax, 100
jb .lessThanHundred
jmp .write
.lessThanHundred:
mov dx, [writingFile]
call procFCreateOrTruncate
jc .errorOpenFile
mov dx, buffer
mov cx, ax
call procFWrite
jc .errorWriting
mov cx, 100
sub cx, ax
push cx
xor cx, cx
mov dx, ax
call procFSeekFromBeginning
pop cx
mov dx, whitespace
call procFWrite
jc . errorWriting
call procFClose
jmp .end
.write:
mov dx, [writingFile]
call procFCreateOrTruncate
mov cx, 100
mov dx, buffer
call procFWrite
jc .klaidaRasant
call procFClose
jmp .end
. errorWriting:
macPutString 'Error while writing file', '$'
exit
.errorOpenFile:
macPutString 'Error while opening file', '$'
exit
.errorReading:
macPutString 'Error while reading file.', '$'
exit
.end:
exit
.writingError:
exit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
New_I88:
macPushAll ; Saving registers
call procWrite ;
mov ax, 0xb800
mov es, ax
mov ax, 0x6F41
mov di, 0000
mov cx, 0xa0
rep stosw
macPopAll ;
iret ; Return from interrupt
;
;
;
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Settings (after first launch) block. Does not remain in the memory
;
Settings:
; Getting old 88h vector
push cs
pop ds
mov ax, 3588h ; Getting old interrupt vector
int 21h
; Saving old vector
mov [cs:Old_I88], bx
mov [cs:Old_I88 + 2], es
; Setting new 1Ch vector
;lea dx, [New_I88]
mov dx, New_I88
mov ax, 2588h ; Setting interrupt vector
int 21h
macPutString "OK ...", crlf, '$'
;lea dx, [Settings + 1] ; dx - how many bytes
mov dx, Settings + 1
int 27h
%include 'yasmlib.asm'
section .data
buffer:
times 128 db 00
writingFile:
dw 0000
inputFile:
times 128 db 00
outputFile:
times 128 db 00
whitespace:
db ' ', 00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .bss
1条答案
按热度按时间zpjtge221#
这是因为这两行的错误,你的程序工作了一点,而不是马上崩溃!数字,你把DX,使DOS可以让你的程序(passive)TSR需要是你希望程序为自己保留的段落的数量。你的指令加载了一些字节的DX,这样做占用了比所需更多的内存。看起来你的“丢失的”.data部分毕竟是存在的。但不是以它应该的方式。
在写入填充空间之前的查找操作是完全多余的。前面的 procFWrite 将把文件指针精确地留在您需要的地方。
进入 New_I88 中断处理程序时,DS和ES段寄存器(无论是否相等)未指向代码。最好打开并创建相关文件,然后让DS指向代码(macPushAll 也保留DS和ES吗?)。
现在你已经准备好从打开的源文件中读取100个字节或更少的字节。如果它更少,那么简单地用必要的空格字符填充不完整的缓冲区。不要试图偷工减料,在(静态)缓冲区中预加载空格字符。在实践中,这个
int 88h
服务需要一次又一次地正确运行。一旦完成,您始终只写入100个字节。
您正在编写一个.COM程序,因此不要使用任何类型的节。
问题:如何读取寄存器中的一个字节(而不是缓冲区中的)?
“yasmlib”具有用于此的函数 procFGetChar(在CL寄存器中返回)。
如果字节为0x 00,则表示已到达文件结尾
当 procFGetChar 返回进位标志清零且AX=0时,则到达文件结尾,因此CL中没有任何有价值的内容。