这是我的源代码:
SECTION .data
EatMsg: db "Hello Koray",10
EatLen: equ $-EatMsg
SECTION .bss
SECTION .text
global main
main:
nop
mov eax,4
mov ebx,1
mov ecx,EatMsg
mov edx,EatLen
int 80H
mov eax,1
mov ebx,0
int 80H
我的问题是关于这一部分:
EatLen: equ $-EatMsg
我的理解是 EatLen 是标签(内存地址),其中$ - x的值保持不变。
但是什么 - EatMsg在这里? String EatMsg由14个字符组成,但使用的编码是什么?如果使用ASCII,那么所有字符都是7(或8?)位,不是吗?但是接下来是怎么回事:
EatLen: equ $-EatMsg-2
例如,在控制台中我会看到:
Hello Kora
所以-2实际上会删除2个字符,但这意味着什么,14位(或16位)?汇编中的每个字符都是一个字节吗?
但我也试过像“ğğğüüşşüşü”这样的人物,但是再次“$ -EatMsg-2”再次移除了我减去的字符数。我很确定“ğ”不能适合8位,那么-1怎么会从控制台中看到的字符串中删除1“ğ”?
我希望我要问的是明确的,抱歉英语不是我的母语。
我正在使用32位Ubuntu(v12),如果有任何相关性,这就是我创建可执行文件的方法:
koray@koray-VirtualBox:~/asm/blog$ nasm -f elf -g -F dwarf sandbox.asm
koray@koray-VirtualBox:~/asm/blog$ gcc -o sandbox sandbox.o
koray@koray-VirtualBox:~/asm/blog$ gdb sandbox -tui
答案 0 :(得分:1)
$
是二进制文件中的当前位置
EatMessage
这里是相应标签的地址,因此字符串"Hello Koray",10
的地址
因此,当您编写$-EatMsg
时,您正在计算该字符串的开头与您现在所处的位置之间的差异。您正在计算EatMsg和EatLen地址之间的差异。
因为我们刚好在字符串之后,所以它等于字符串的长度(以字节为单位)。
String EatMsg由14个字符组成,但使用的编码是什么?如果使用ASCII,那么所有字符都是7(或8?)位,不是吗?
你写了'db“Hello Koray”,10',所以你要创建一个字节串。
所以-2实际上会删除2个字符,但这意味着什么,14位(或16位)?汇编中的每个字符都是一个字节吗?
-2从长度上减去2个字节。不是位,字节。 你正在做的是告诉系统调用写11-2 = 9字节,当你的字符串仍然是11字节长。 每个字符在这里恰好是1个字节长(只要你坚持使用ASCII),所以这将打印2个字符。
如果您的字符串具有非ASCII字符,那么这些字符将被编码为多个字节。 例如,如果你写
EatMsg: db "Hello Korayğ",10
EatLen: equ $-EatMsg-2
这将打印Hello Koray�
,因为你不打印最后一个换行符,并且你不打印ğ的最后一个字节,这样你分成两半的最后一个字符就会变成无效的UTF-8字符。
编辑:显然,并非所有终端都显示 字符,但您可以通过查看列表文件(标志-l of nasm)来查看字符串的编码方式