这是我的源代码:
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 是一个 Label (一个内存地址),其中 $ - 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
最佳答案
$
是二进制文件中的当前位置
EatMessage
这里是对应标签的地址,所以字符串"Hello Koray",10
因此,当您编写 $-EatMsg
时,您正在计算该字符串的开头与您现在所在位置之间的差异。您正在计算 EatMsg 和 EatLen 地址之间的差异。
因为我们紧跟在字符串之后,所以它等于字符串的字节长度。
The String EatMsg consists of 14 characters, but what is the encoding used? If ASCII is used then all characters are 7(or 8?) bits, isn't it?
你写了 'db "Hello Koray",10',所以你正在创建一个字节串。
So -2 will actually remove 2 characters but this means what, 14 bits(or 16)? Is every character a byte in Assembly?
-2 从长度中减去 2 个字节。不是位,是字节。 你正在做的是告诉系统调用写入 11-2=9 字节,而你的字符串仍然是 11 字节长。 这里的每个字符恰好是 1 个字节长(只要您坚持使用 ASCII),所以这将少打印 2 个字符。
如果您的字符串包含非 ASCII 字符,这些字符将被编码为多个字节。 例如,如果你写
EatMsg: db "Hello Korayğ",10
EatLen: equ $-EatMsg-2
这将打印 Hello Koray�
因为您没有打印最后一个换行符,也没有打印 ğ 的最后一个字节,所以您分成两半的最后一个 ğ 字符变成了无效的 UTF-8 字符。
编辑:显然,并非所有终端都显示 � 字符,但您可以通过查看列表文件(nasm 的标志 -l)来了解字符串是如何编码的
关于linux - 使用 $ - x 时我们在汇编中减去多少位(或字节),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27847875/