String 以零字节结尾的ASCIIZ字符串

String 以零字节结尾的ASCIIZ字符串,string,assembly,x86,dos,String,Assembly,X86,Dos,我正在编写一个汇编级程序来创建一个文件 .model small .data Fn db "test" .code mov ax,@data mov ds,ax mov CX,00 lea DX,Fn mov ah,3ch int 21h Mov ah,4ch Into 21h End 虽然程序并没有错误,但文件并没有创建,所以我在互联网上搜索原因 然后我找到了阿西兹 因此,我将数据段替换为 .data Fn db "test", 0 成功了 为什么我们需要使用ASCIIZ,为

我正在编写一个汇编级程序来创建一个文件

.model small
.data
 Fn db "test" 
.code
mov ax,@data 
mov ds,ax

mov CX,00
lea DX,Fn

mov ah,3ch
int 21h

Mov ah,4ch
Into 21h
End
虽然程序并没有错误,但文件并没有创建,所以我在互联网上搜索原因

然后我找到了阿西兹

因此,我将数据段替换为

.data
Fn db "test", 0 
成功了


为什么我们需要使用ASCIIZ,为什么不能使用普通字符串创建文件?

假设您的
部分中有多个字符串

Fn db "test" 
s1 db "aaa"
s2 db "bbb"
编译时,
.data
节将依次包含所有3个字符串:

0x74 0x65 0x73 0x74 0x61 0x61 0x61 0x62 0x62 0x62
这是
testaabbb
的二进制表示形式

函数必须有一种方法来确定第一个字符串的结束位置和第二个字符串的开始位置。此“标记”为0x00字节(“\x00”),也称为“空字节终止字符串”或ASCIIZ,这样您就可以知道字符串的结束位置:

Fn db "test",0
s1 db "aaa",0x00 ; is the same
s2 db "bbb\x00" ; still same thing
现在,您的
.data
部分将如下所示

0x74 0x65 0x73 0x74 0x00 0x61 0x61 0x61 0x00 0x62 0x62 0x62 0x00

这是
test\x00aaa\x00bbb\x00
,现在字符串之间有了一个分隔符,因此当您向函数提供字符串的起始地址时,它将知道字符串的确切结束位置。

在不知道您使用的是什么操作系统的情况下,很难说,但我猜您尝试使用的例程需要一个“正常的”C字符串,必须以0字节结尾。您的原始代码不能保证“test”之后的内容,因此它很可能是任何内容,包括文件系统中非法的字符。因为如果您使用
ah=3ch
读取,它会告诉您文件名字符串必须以零结尾。否则,它将如何知道字符串的末尾在哪里?而且
Fn db“test”
不会自动归零并终止字符串。它必须是显式的。@Joe:INT 21h是典型的MS-DOS(及其派生)系统调用。旁白:请务必阅读文档。根据@Lougler的评论,将字符串打印到
stdin
Int 21h函数09h要求字符串以美元结尾
$
。当您在末尾列出数据部分的内容时,您忘记了
“bbb”
后面的NUL字节。@Michael谢谢,已将其更改