【问题标题】:ASCIIZ string ending with a zero byte以零字节结尾的 ASCIIZ 字符串
【发布时间】:2015-05-11 16:20:19
【问题描述】:

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

.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

虽然程序没有错误,但没有创建文件,所以我在网上搜索了原因。

然后我找到了 ASCIIZ。

所以我用

替换了数据段
.data
Fn db "test", 0 

成功了。

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

【问题讨论】:

  • 不知道您使用的是什么操作系统,这很难说,但我猜您尝试使用的例程需要一个“正常”C字符串,必须以 0 字节结束。您的原始代码不能保证“测试”之后会发生什么,因此它很可能是任何东西,包括对您的文件系统来说非法的字符。
  • 因为如果您使用ah = 3ch 阅读documentation regarding int 21h,它会告诉您文件名字符串必须以零结尾。否则,它怎么知道字符串的结尾在哪里?并且Fn db "test" 不会自动归零终止字符串。它必须是明确的。
  • @Joe:INT 21h 是一个典型的 MS-DOS(和衍生)系统调用。
  • 旁白:始终阅读文档。根据@lurker 的评论,将字符串打印到stdin Int 21h 函数09h 要求字符串以美元结尾$

标签: string assembly x86 dos


【解决方案1】:

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

Fn db "test" 
s1 db "aaa"
s2 db "bbb"

当你编译它时,.data 部分将包含所有 3 个字符串,一个接一个:

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

这是testaaabbb的二进制表示。

函数必须有一种方法来确定第一个字符串的结束位置和第二个字符串的开始位置。这个“标记”是 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,现在你在字符串之间有了一个分隔符,所以当你向函数提供字符串的起始地址时,它会知道你的字符串到底在哪里结束。

【讨论】:

  • 你在最后列出数据部分的内容时忘记了"bbb"后面的NUL字节。
  • @Michael 谢谢,改了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-06
相关资源
最近更新 更多