如何打印字符串的长度在装配
我学习组件使用以下的Hello World程序如何打印字符串的长度在装配
section .text
global _start ;must be declared for linker (ld)
_start: ;tells linker entry point
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
msg db 'Hello, world!', 0xa ;our string
len equ $ - msg ;length of our string
原来的问题我是什么是字符串的长度的意思。这是否意味着字符数或内存中的长度(字节数)? 检查这个我想打印变量len。我怎样才能做到这一点?我天真地试图定义新的变量
len2 equ $ - len
,然后改为运行
mov edx,len2 ;message length
mov ecx,len ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
尝试打印LEN,但这种印刷什么。如何打印由len代表的号码?
...
mov edx,len ;message length
这会加载edx
带有某种数值,如14这种情况下。 len
是“当量”恒定符号,像在#define
C.
mov ecx,msg ;message to write
此加载与ecx
第一个字符的地址(msg
是标签,指向存储器)。
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
...
msg db 'Hello, world!', 0xa ;our string
这定义了14个字节的存储器,其值为72('H'),101('e')......。第一个字节由msg
标签(它的内存地址)指向。
len equ $ - msg ;length of our string
这定义了编译时可见的常量len
。它没有定义任何内存内容,所以你不能在可执行文件或运行时找到它(除非使用,例如mov edx,len
,那么它就会被编译成特定的指令)。
的定义是$ - msg
,将$
在这方面的工作为“当前地址”,下一个定义的机器代码的字节将被编译,所以在这个地方它等于msg + 14
(我希望我没有算人数字符正确:))。并且((msg+14) - msg) = 14
=定义在len
的定义和标签msg
之间的存储器中定义的字节数。
请注意,我如何避免字作为变量或字符,ASM是更低的水平,所以标签到内存和字节是更准确的措辞,我希望它会帮助你识别细微的差异。
你len2 equ $ - len
的len
后也这样定义len2
为(msg+14)
减len
这是14
(仍然存在于内存中,通过定义len
不添加任何新的字节),让你有效地定义len2
等于msg
值。
然后:
mov edx,len2 ;message length
mov ecx,len ;message to write
...
是否与指针调用sys_write
串等于14
(无效存储器参考,该内存区域是禁止普通用户代码),并且长度等于地址msg
,这将在32b linux上很可能有一些值,如0x80004000
,即超过2G的字符输出。
sys_write
自然不会那样,失败并返回错误代码eax
。
要输出什么关系sys_write
,你必须首先将其写入内存ASCII(我觉得UTF8默认情况下,在Ubuntu外壳支持,但懒得去核实)编码字符串,并赋予该内存的sys_write
地址安慰和字节长度(UTF8字符串字节和字符之间的差异很重要,sys_write
不知道字符,它与二进制文件和字节一起工作,所以长度是字节量)。
我不会写代码输出数字,因为这是几行(实现简化的printf
),SO有几个Q + A,但我希望我的解释能帮助你理解发生了什么,以及如何有用。
如果你刚开始学习ASM,认为无论是链接到的clib
有printf
可用的,甚至更好,使用调试器和调试器在寄存器中直核实值,不串输出困扰了,这是一个有点更高级的话题,然后是最初的算法,以及基本的流量控制和操作堆栈。在你更熟悉基本指令的工作方式以及如何调试代码之后,然后尝试输出数字会更容易。
您可能需要检查[**如何在汇编NASM中打印数字**](https://*.com/questions/8194141/how-to-print-a-number-in-assembly- nasm)简短的回答是你写*字符*到'stdout'。数字是一个十进制值,而不是可以立即写入的字符串,您必须将整数或无符号值转换为其字符表示形式,然后将其写入'stdout'。 –
出于好奇,你编程的操作系统是什么?视窗? Unix的?苹果系统?我在问,因为在这样的问题之上,经常有人问这个问题是否使用了错误平台的教程。 –
谢谢。我正在使用Ubuntu。出于好奇,当我尝试直接使用stdout打印数字时,我什么也没有得到。为什么它不打印什么,而不是打印一些废话? –