如何在程序集中写入新行

时间:2014-05-26 14:31:55

标签: file assembly

我使用Windows 8.1和模拟器进行程序集8086。

我在下面写了汇编代码,在文件中写了2条消息,但它不正确,因为它没有在两条消息之间写新行。

  

输出:Masoud Hosseini

data segment

    fname  DW  "c:\test.txt"
    len    DW  8   
    handel DW  ?
    endl   DB  13
    msg1   DB  "Masoud  "
    msg2   DB  "Hosseini"

ends

code segment
start:

    mov ax, data
    mov ds, ax
    mov es, ax

    mov ah, 3ch  ;open file
    lea dx, fname
    int 21h

    mov handel, ax    ;save handel

    lea dx, msg1
    mov bx, handel
    mov cx, len
    mov ah, 40h
    int 21h

    lea dx, endl
    mov bx, handel
    mov cx, 1 
    mov ah, 40h
    int 21h

    lea dx, msg2
    mov bx, handel
    mov cx, len
    mov ah, 40h
    int 21h

    mov ax, 4c00h
    int 21h    
ends

end start

1 个答案:

答案 0 :(得分:1)

1)您的文件名错误。 INT 21h/3Ch期望ASCIIZ字符串,即ASCII字节加空(如C)。你写了一系列没有任何分隔符的ASCII 单词

2)另外INT 21h/3Ch期望CX中的文件属性。 “Ralf Brown的中断列表”是查找INT 21h函数的一个很好的资源:http://www.delorie.com/djgpp/doc/rbinter/ix/21/

3)换行符(endl)的编码取决于操作系统。 DOS需要两个字节:0Dh& 0AH。 Linux和现代Windows仅满足于0Ah。较旧的Mac想要0Dh。这些编码字节应写为字符。

4)最后你必须关闭文件。

TASM的例子:

.MODEL small
ASSUME CS:code, DS:data

data segment

    fname  DB  "test.txt",0
    len    DW  8
    handel DW  ?
    endl   DB  0Dh,0Ah          ; CR & LF (DOS)
    msg1   DB  "Masoud  "
    msg2   DB  "Hosseini"

ends

code segment
start:

    mov ax, data
    mov ds, ax
    mov es, ax

    mov ah, 3ch         ; CREATE OR TRUNCATE FILE
    lea dx, fname       ; DS:DX -> ASCIZ filename
    xor cx, cx          ; file attributes
    int 21h             ; DOS INTERRUPT
    jc err_exit

    mov handel, ax      ; save handel

    lea dx, msg1        ; ds:dx -> data to write
    mov bx, handel      ; file handle
    mov cx, len         ; number of bytes to write
    mov ah, 40h         ; WRITE TO FILE OR DEVICE
    int 21h             ; DOS INTERRUPT

    lea dx, endl        ; ds:dx -> data to write
    mov bx, handel      ; file handle
    mov cx, 2           ; number of bytes to write
    mov ah, 40h         ; WRITE TO FILE OR DEVICE
    int 21h             ; DOS INTERRUPT

    lea dx, msg2        ; ds:dx -> data to write
    mov bx, handel      ; file handle
    mov cx, len         ; number of bytes to write
    mov ah, 40h         ; WRITE TO FILE OR DEVICE
    int 21h             ; DOS INTERRUPT

    mov bx, handel      ; file handle
    mov ah, 3Eh         ; CLOSE FILE
    int 21h             ; DOS INTERRUPT

exit:
    mov ax, 4c00h       ; Exit (0)
    int 21h             ; DOS INTERRUPT

err_exit:
    mov ah, 4ch         ; Exit (AX)
    int 21h             ; DOS INTERRUPT
ends

end start


.MODEL small
ASSUME CS:code, DS:data

data segment

    fname  DB  "test.txt",0
    len    DW  8
    handel DW  ?
    endl   DB  0Dh,0Ah          ; CR & LF (DOS)
    msg1   DB  "Masoud  "
    msg2   DB  "Hosseini"

ends

code segment
start:

    mov ax, data
    mov ds, ax
    mov es, ax

    mov ah, 3ch         ; CREATE OR TRUNCATE FILE
    lea dx, fname       ; DS:DX -> ASCIZ filename
    xor cx, cx          ; file attributes
    int 21h             ; DOS INTERRUPT
    jc err_exit

    mov handel, ax      ; save handel

    lea dx, msg1        ; ds:dx -> data to write
    mov bx, handel      ; file handle
    mov cx, len         ; number of bytes to write
    mov ah, 40h         ; WRITE TO FILE OR DEVICE
    int 21h             ; DOS INTERRUPT

    lea dx, endl        ; ds:dx -> data to write
    mov bx, handel      ; file handle
    mov cx, 2           ; number of bytes to write
    mov ah, 40h         ; WRITE TO FILE OR DEVICE
    int 21h             ; DOS INTERRUPT

    lea dx, msg2        ; ds:dx -> data to write
    mov bx, handel      ; file handle
    mov cx, len         ; number of bytes to write
    mov ah, 40h         ; WRITE TO FILE OR DEVICE
    int 21h             ; DOS INTERRUPT

    mov bx, handel      ; file handle
    mov ah, 3Eh         ; CLOSE FILE
    int 21h             ; DOS INTERRUPT

exit:
    mov ax, 4c00h       ; Exit (0)
    int 21h             ; DOS INTERRUPT

err_exit:
    mov ah, 4ch         ; Exit (AX)
    int 21h             ; DOS INTERRUPT
ends

end start