assembly 程序集中的换行符和空终止字符串

oxf4rvwz  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(110)

我是一个新手,我正在看一个Hello World程序:

section .data
    hello:     db 'Hello, World!',10    ; 'Hello, World!' plus a linefeed character
    helloLen:  equ $-hello             ; Length of the 'Hello world!' string

section .text
    global _start

_start:
    mov eax,4            ; The system call for write (sys_write)
    mov ebx,1            ; File descriptor 1 - standard output
    mov ecx,hello        ; Put the offset of hello in ecx
    mov edx,helloLen     ; helloLen is a constant, so we don't need to say
                         ;  mov edx,[helloLen] to get it's actual value
    int 80h              ; Call the kernel
    mov eax,1            ; The system call for exit (sys_exit)
    mov ebx,0            ; Exit with return "code" of 0 (no error)
    int 80h;

关于db 'Hello, World!',10的问题这就是“Hello,World!“字符串以换行符结束,但据我所知,字符串必须以空字符结束,我从另一个来源了解到的是将字符串创建为db "Hello, World!,0
如何在字符串的末尾(或内部)添加换行符/换行符,并在最后添加null终止符?
(我确实理解,在给定的程序中,代码是使用给定的长度打印的,这是一个选项,但是null终止的字符串似乎更好,必须为你将要编写的每个字符串提供长度似乎不是很好)

ffdz8vbo

ffdz8vbo1#

(我不小心忽略了你的最后一句话,所以这个答案的第一部分是解释你可能已经知道的。我会把它留在这里,以防对未来的读者有帮助。
从我所知道的字符串必须以空字符终止
的确,空结束符是一种非常常见的标记字符串结尾的方式,而且许多函数都设计用于处理这种形式的字符串;例如标准C库中的所有str*函数。人们经常使用“字符串”这个词来表示“以空值终止的字符串”,而没有进一步澄清。
但是write系统调用不是这些函数之一。它不依赖于空终止符来标记要写入的数据的结束;相反,它使用长度参数(您已将其放入edx寄存器中)来了解应从内存中向文件描述符写入多少字节。如果你仔细想想,它必须是这样的:如果write使用空终止字符串,那么就不可能使用它来编写需要包含空字节的二进制文件。
因此,在程序中,由于您对hello消息所做的唯一事情就是将其传递给write系统调用,因此无需包含终止空字节。它只会浪费一个字节的内存。
如果你想包含一个终止空字节(也许是因为你想在str*函数,printf等中使用这个字符串),那么只需附加一个0:

hello:     db 'Hello, World!', 10, 0

你没有提到你使用的汇编器,但它看起来像nasm。nasm文档非常完整,它解释了db指令可以接受任意的字符串和数值表达式列表。
请注意,如果您保留下面的helloLen定义,则该长度将 * 包括 * 终止null,这可能不是您想要的。但是如果你使用的是通过null终止符检测长度的函数,那么你可能根本不需要helloLen

相关问题