在程序集中写入文件

Write to file in Assembly

我的任务是将缓冲区和一些其他文本打印到文件中,当我使用这段代码时,我得到了错误的答案。输出缓冲区是可以的,它可以完美打印,但是当我尝试打印在数据中声明的文本时,开始出现无意义的情况。例如,当我尝试打印 "Hello (letters )" 时,它给了我这个 "Hello (9 spaces)(letters$)$"。当我为每个字符串编写 3 个不同的过程时,它会正确打印。伙计们,也许你能帮我找出问题所在?

model small

BufSize EQU 60

.stack 100h
.data
    rez db "rez.txt", 
    Buf db BufSize dup (?)
    handle  dw ?
    Letters db 0
    brackets1 db " (letters$"
    brackets2 db ")$"
.code
start:
    MOV ax, @data
    MOV ds, ax

    MOV ah, 3Ch
    MOV cx, 0
    MOV dx, offset rez
    INT 21h              ;results file is created and opened
    MOV handle, ax

    MOV cx, 5            ;5 bytes ("Hello")
    ADD cx,10            ;10 bytes from "(letters " and ")"
    MOV bx, handle
    CALL    Write

    MOV ah, 3Eh
    MOV bx, handle
    INT 21h              ;close file

    MOV ah, 4Ch
    MOV al, 0
    INT 21h 

PROC Write
    PUSH    dx

    MOV ah, 40h
    MOV dx, offset Buf
    INT 21h          ;Write to file

    MOV ah,40h
    MOV dx,offset brackets1
    INT 21h 

    MOV ah,40h
    MOV dx,offset brackets2
    INT 21h

    POP dx
    RET
RasykBuf ENDP

END start   

我添加了一些省略的说明和新评论;我更正了一个编译错误:RasycBuf ENDPWrite 不是 PROCedure 的名称吗?)。每当你执行一个 I/O 操作时,你必须检查它是否成功完成,否则下一个 I/O 的操作会产生一个 运行-TIME 的错误。 我已经成功编译了这个源代码。 但是我不知道你想要它做什么,因为正如另一个用户所说,这个程序是不完整的。

model small

BufSize EQU 60

.stack 100h
.data
    rez db "rez.txt", 0       ; NULL TERMINATOR WAS OMIT.
    Buf db BufSize dup (32)   ; CHARACTERS WITHOUT A PURPOSE (SPACES).
    ;handle  dw ?             ; NOT NEEDED.
    ;Letters db 0             ; NOT USED.
    brackets1 db " (letters$"
    brackets2 db ")$"
.code
start:
    MOV ax, @data
    MOV ds, ax

    MOV ah, 3Ch
    MOV cx, 0
    MOV dx, offset rez
    ; AH      -> 3CH, CREATE A FILE WITH HANDLE.
    ; CX      -> Attribute for file:
    ;            Bit0: read-only.
    ;            Bit1: hidden.
    ;            Bit2: system.
    ;            Bit3: volume-label.
    ;            Bit4: directory.
    ;            Bit5: archive.
    ;            Bit6: UNKNOWN.
    ;            Bit7: shareable.
    ; DS:DX   -> ASCIZ file-name (with optional drive and path).
    ; OUTPUT  -> FCarry=1:       ERROR, AX= error-code;
    ;            FCarry=0: SUCCESSFULL, AX= file-handle.
    INT 21h              ; Results file is created and opened.
    JB  openfailed       ; If error, exit.
    ;MOV handle, ax      ; Not needed.

    ;MOV cx, 5           ; 5 bytes ("Hello")
    ;ADD cx, 10          ; 10 bytes from "(letters " and ")"
    MOV bx, ax           ; Copy file-handle into BX's reg.
    CALL    Write

    MOV ah, 3Eh
    ;MOV bx, handle      ; BX's reg. already contains handle.
    ; AH      -> 3EH, CLOSE A FILE WITH HANDLE.
    ; BX      -> File-handle
    ; OUTPUT  -> FCarry=1:       ERROR, AX= error-code;
    ;            FCarry=0: SUCCESSFULL.
    INT 21h              ; Close file

openfailed:
    MOV ah, 4Ch
    MOV al, 0
    ; AH      -> 4CH, QUIT WITH EXIT CODE (EXIT).
    ; AL      -> EXIT CODE.
    INT 21h

Write:
    ; I suppose that you want to write the content of the buffer (Buf),
    ; followed by brackets1 and brackets2 strings.
    ; NOTE: Buf CONTAINS ONLY CHARACTERS WITHOUT A PURPOSE !
    ;PUSH    dx          ; Because DX's reg. is only used here, don't need to PUSH/POP it

    MOV ah, 40h
    MOV cx, BufSize      ; Size of Buf
    MOV dx, offset Buf
    ;  AH     -> 40H, WRITE TO FILE WITH HANDLE
    ;  BX     -> Handle
    ;  CX     -> Buffer's size
    ;  DS:DX  -> Buffer
    ; OUTPUT  -> FCarry=1:       ERROR, AX= error-code;
    ;            FCarry=0: SUCCESSFULL, AX= num. of byte written.
    INT 21h              ; Write to file
    JB  error            ; If error, return

    MOV ah, 40h
    MOV cx, 10           ; Size of brackets1's string
    MOV dx, offset brackets1
    ;  AH     -> 40H, WRITE TO FILE WITH HANDLE
    ;  BX     -> Handle
    ;  CX     -> Buffer's size
    ;  DS:DX  -> Buffer
    ; OUTPUT  -> FCarry=1:       ERROR, AX= error-code;
    ;            FCarry=0: SUCCESSFULL, AX= num. of byte written.
    INT 21h
    JB  error            ; If error, return

    MOV ah, 40h
    MOV cx, 2            ; Size of brackets2's string
    MOV dx, offset brackets2
    ;  AH     -> 40H, WRITE TO FILE WITH HANDLE
    ;  BX     -> Handle
    ;  CX     -> Buffer's size
    ;  DS:DX  -> Buffer
    ; OUTPUT  -> FCarry=1:       ERROR, AX= error-code;
    ;            FCarry=0: SUCCESSFULL, AX= num. of byte written.
    INT 21h
error:
    ;POP dx              ; Because DX's reg. is only used here, don't need to PUSH/POP it
    RET

END start