2017-06-27 23 views
1

我目前正在按照Kip Irvine的“汇编语言x86编程”一书学习汇编编程。以零结尾的字符串和在x86汇编语言中不以null结尾的字符串之间有什么区别

在该书中,作者指出

串的最常见的类型与(含0)一个空字节结束。 叫了个空值终止字符串

在本书的后续部分,笔者有一个字符串,例如没有空字节

greeting1 \ 
BYTE "Welcome to the Encryption Demo program " 

所以我只是想知道,什么是之间的不同null终止的字符串和在x86汇编语言中不以null结尾的字符串?它们可以互换吗?或者他们不是彼此等同?

+2

如何获得'greeting2'的长度?使用'greeting1',您可以查找第一个空字节。例1类似于C,例2类似于Java(Java'String'存储长度)。 –

+0

@ElliottFrisch感谢您的评论。纠正我,如果我错了,但我对x86汇编语言字符串的理解是:字符串可以定义有或没有null在最后,我们可以确定字符串的长度在最后null,但同样不能为没有null的字符串完成。我的理解是否正确?还有其他的区别吗? – Thor

+1

考虑还存储可能包含多个'\ 0'(s)的字符串。我真的不能想到另一个。但也许你可以。祝你好运。 –

回答

3

这里没有什么特别的asm;这与C中的问题是一样的。关于如何将字符串存储在内存中并跟踪它们结束的位置。

以空结尾的字符串和不以null结尾的字符串之间有什么不同?

一个空结束的字符串有后一个0字节,所以你可以找到与strlen结束。 (或rep scasb)。这可以用作隐式长度字符串,就像C用法一样。

它们是可以互换的吗?

如果您知道空终止字符串的长度,您可以将指针+长度传递给需要显式长度字符串的函数。该函数永远不会查看0字节,因为您将传递一个不包含0字节的长度。这不是字符串数据的一部分。

但是,如果你有一个没有终结符的字符串,你不能将它传递给一个函数或系统调用,它需要一个以空字符结尾的字符串。 (如果内存是可写的,你可以在字符串后存储0,使之变成一个空结尾的字符串。)


在Linux中,许多系统调用需要字符串作为C风格的隐含长度空值终止字符串。 (即只是一个char*而不通过一段长度)。

例如,open(2)需要一个字符串作为路径:int open(const char *pathname, int flags);您必须将一个以空字符结尾的字符串传递给系统调用。在Linux中创建一个名称包含'\0'的文件是不可能的(与其他大多数Unix系统一样),因为处理文件的所有系统调用都使用以空字符结尾的字符串。

OTOH,write(2)需要一个内存缓冲区,它不一定是一个字符串。它有签名ssize_t write(int fd, const void *buf, size_t count);。它不关心在buf+count0,因为它只查看从bufbuf+count-1的字节。

可以将字符串传递给write()。它不关心。它基本上只是内核页面缓存的一个memcpy(或者到一个管道缓冲区或任何非常规文件)。但就像我说的,你不能通过一个任意的非终止缓冲区作为路径参数为open()

或者它们并不相等?

隐式长度和显式长度是跟踪内存中字符串数据/常量并传递它们的两种主要方式。他们解决同样的问题,但方式相反。

如果您有时需要在穿过它们之前找到它们的长度,那么长的隐式长度字符串是一个不错的选择。通过字符串循环比读取整数要慢很多。查找隐式长度字符串的长度为O(n),但显式长度的字符串当然是O(1)时间来查找长度。 (这是已知的!)。至少以字节为单位的长度是已知的,但如果使用UTF-8或UTF-16等可变长度编码,则Unicode字符的长度可能不知道。

2

字符串如何终止与程序集无关。从历史上看,'$',CRLF [10,13]或[0A,0D]在Linux下与GEDIT有时相反。约定取决于系统如何与自身或其他系统进行交互。举个例子,我的应用程序严格围绕着ASCII,因此,如果我读取的是UTF-8或16的文件,我的应用程序就会失败。 NULL或任何类型的终止都可以是可选的。

考虑这个例子

Title: db 'Proto_Sys 1.00.0', 0, 0xc4, 0xdc, 0xdf, 'CPUID', 0, 'A20', 0 
     db 'AXCXDXBXSPBPSIDIESDSCSSSFSGS' 
Err00: db 'Retry [Y/N]', 0 

我实现了,如果CX = 0,那么它假设一个NULL结尾的字符串是要显示其中一个套路,否则只有一个字符被读取并重复CX次。这就是为什么0xc4 0xdc 0xdf未终止。同样,'重试[Y/N]'之前没有终止符,因为我的算法的设计方式不需要。

你需要关心的唯一事情是数据的来源是什么,或者你的应用程序需要与其他东西兼容。然后你只需简单地实现你需要的任何工具。

相关问题