将换行符输出到文件的问题

时间:2016-03-14 17:36:04

标签: 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

我正在使用 MASM DOSBOX 。问题是虽然程序在两个不同的行中打印数据,但在第二行之前,它还会打印一些奇怪的字符,然后打印字符串msg。这个程序有什么问题,我该如何解决?

1 个答案:

答案 0 :(得分:5)

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

mov cx,28h

我认为你打算用28位小数。修改与上面匹配的两行

mov cx,28

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

MSGLEN equ $-msg

所以代码看起来像:

msg db 'Prashant Pandey 2014A7PS100G'
MSGLEN equ $-msg

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

mov cx, MSGLEN

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

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

msg db 'Prashant Pandey 2014A7PS100G',13,10
MSGLEN equ $-msg

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