assembly 如何在YASM中通过中断将数据从一个文件传输到另一个文件

zte4gxcn  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(138)

我正在写我自己的中断,从一个文件到另一个文件传输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
zpjtge22

zpjtge221#

mov  dx, Settings + 1
int  27h

这是因为这两行的错误,你的程序工作了一点,而不是马上崩溃!数字,你把DX,使DOS可以让你的程序(passive)TSR需要是你希望程序为自己保留的段落的数量。你的指令加载了一些字节的DX,这样做占用了比所需更多的内存。看起来你的“丢失的”.data部分毕竟是存在的。但不是以它应该的方式。

push cx
xor cx, cx
mov dx, ax
call procFSeekFromBeginning
pop cx

在写入填充空间之前的查找操作是完全多余的。前面的 procFWrite 将把文件指针精确地留在您需要的地方。
进入 New_I88 中断处理程序时,DS和ES段寄存器(无论是否相等)未指向代码。最好打开并创建相关文件,然后让DS指向代码(macPushAll 也保留DS和ES吗?)。

; IN (ds:dx,es:cx)
procWrite:         
  push es cx
  call procFOpenForReading    ; -> BX CF
  pop  dx ds
  jc   .errorOpenFile
  mov  [cs:Handle1], bx
  call procFCreateOrTruncate  ; -> BX CF
  jc   .errorOpenFile
  mov  [cs:Handle2], bx
  push cs
  pop  ds

现在你已经准备好从打开的源文件中读取100个字节或更少的字节。如果它更少,那么简单地用必要的空格字符填充不完整的缓冲区。不要试图偷工减料,在(静态)缓冲区中预加载空格字符。在实践中,这个int 88h服务需要一次又一次地正确运行。

mov  dx, buffer
  mov  cx, 100
  mov  bx, [Handle1]
  call procFRead              ; -> AX=[0,100] CF
  jc   .errorReading
  call procFClose             ; -> CF
  jc   .errorReading
  mov  bx, ax
padBuffer:
  cmp  bx, 100
  jnb  .write
  mov  [buffer + bx], byte 32
  inc  bx
  jmp  padBuffer

一旦完成,您始终只写入100个字节。

.write:
  mov  dx, buffer
  mov  cx, 100
  mov  bx, [Handle2]
  call procFWrite             ; -> AX CF
  jc   .errorWriting
  call procFClose             ; -> CF
  jc   .errorWriting
  ret

您正在编写一个.COM程序,因此不要使用任何类型的节。

%include 'yasmmac.inc'

  org 100h  

  jmp  Settings               ; Execution starts here
  nop

Old_I88:  dw 0, 0
Handle1:  dw 0
Handle2:  dw 0
buffer:   times 100 db 0
; ----------------------------
proWrite:
  ...
  ret
; ----------------------------
New_I88:                                           
  ...
  iret
; ----------------------------
  %include 'yasmlib.asm' 
; ----------------------------
Settings:
  mov  ax, 3588h
  int  21h
  mov  [Old_I88], bx             
  mov  [Old_I88 + 2], es         
  mov  dx, New_I88
  mov  ax, 2588h
  int  21h   
  ...
  mov  dx, (Settings + 15) / 16      ; Number of paragraphs to keep
  int  27h

问题:如何读取寄存器中的一个字节(而不是缓冲区中的)?

“yasmlib”具有用于此的函数 procFGetChar(在CL寄存器中返回)。
如果字节为0x 00,则表示已到达文件结尾
procFGetChar 返回进位标志清零且AX=0时,则到达文件结尾,因此CL中没有任何有价值的内容。

相关问题