将换行符输出到文件时出现问题

Pra*_*dey 3 assembly dos masm dosbox x86-16

我正在编写一个DOS程序来制作文件并将其写入。我必须在两行中写入数据。这是我的代码:

.model tiny
.486
.data

fname db 'file5.txt',0
handle dw ?
msg db 'Prashant Pandey 2014A7PS100G'

.code
.startup
mov ah,3eh
mov bx,handle
int 21h

mov ah,3ch      ;the 4 lines from now open an new non-existing.3ch is used to open a new file
lea dx,fname
mov cl,2h
int 21h
mov handle,ax

mov ah,40h      ;these 4 lines write to the already opened file
mov bx,handle
mov cx,28h
lea dx,msg
int 21h

; new line
mov dx,13
mov ah,2
int 21h  
mov dx,10
mov ah,2
int 21h

mov ah,40h      ;these 4 lines write to the already opened file
mov bx,handle
mov cx,28h
lea dx,msg
int 21h 

mov ah,3eh
mov bx,handle
int 21h

.exit
end
Run Code Online (Sandbox Code Playgroud)

我正在使用MASMDOSBOX。问题是尽管程序在两行中打印数据,但是在第二行之前,它还打印了一些奇怪的字符,然后打印了字符串msg。该程序有什么问题,如何解决?

Mic*_*tch 5

您的代码中有几个问题。您的字符串Prashant Pandey 2014A7PS100G长度为28个字符,但是在写入文件时,请根据说明指定28h(十六进制):

mov cx,28h
Run Code Online (Sandbox Code Playgroud)

我认为您的意思是使用28位小数。修改与上面匹配的两行

mov cx,28
Run Code Online (Sandbox Code Playgroud)

更好的解决方案是让汇编器为您计算长度。这可以通过创建一个代表字符串长度的常量来完成。一个例子是在定义后立即写出msg

MSGLEN equ $-msg
Run Code Online (Sandbox Code Playgroud)

因此,代码如下所示:

msg db 'Prashant Pandey 2014A7PS100G'
MSGLEN equ $-msg
Run Code Online (Sandbox Code Playgroud)

$是当前位置计数器的等效项。在使用msg db位置计数器定义字符串之后,将立即是的最后一个字符之后的字节位置msg。如果msg从中减去标签的地址,则将获得字符串的长度。在EQU指令有效地创建一个恒定值,然后可以在代码中使用。现在您可以像这样使用它:

mov cx, MSGLEN
Run Code Online (Sandbox Code Playgroud)

现在,您可以修改msg字符串,而不必担心在代码中手动调整大小。


代码的第二个问题是INT 21h / AH = 2h写入标准输出(如果不将其重定向到其他地方,则默认情况下写入控制台)。您的代码将换行符写入标准输出而不是文件。您可以msg使用以下代码向其自身添加换行符来解决此问题:

msg db 'Prashant Pandey 2014A7PS100G',13,10
MSGLEN equ $-msg
Run Code Online (Sandbox Code Playgroud)

或者,您可以定义另一个包含13,10在其中的字符串,并使用INT 21 / AH = 40h将该字符串写出来msg