这是我的源代码:
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在这里是什么?字符串EatMsg由14个字符组成,但所使用的编码是什么?如果使用ASCII,那么所有字符都是7(或8?)一点点,不是吗?但这是怎么做到的呢?
EatLen: equ $-EatMsg-2例如,我将在控制台中看到:
你好科拉
SO-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发布于 2015-01-08 19:31:27
$是二进制文件中的当前位置。
EatMessage这里是对应标签的地址,所以字符串"Hello Koray",10的地址
因此,当您编写$-EatMsg时,您正在计算该字符串的开头与现在的位置之间的差异。您正在计算EatMsg和EatLen地址之间的差异。
因为我们只需要字符串,这等于字符串的长度(以字节为单位)。
字符串EatMsg由14个字符组成,但所使用的编码是什么?如果使用ASCII,那么所有字符都是7(或8?)一点点,不是吗?
您编写了“db”"Hello“,10‘,所以您正在创建一个字节字符串。
SO-2将实际删除2个字符,但这意味着,14位(或16位)?程序集中的每个字符都是字节吗?
-从长度中减去2个字节。不是比特字节。您正在做的是告诉syscall编写11-2=9个字节,而您的字符串仍然是11个字节长。这里的每个字符恰好有一个字节长(只要您坚持使用ASCII),这样就会少打印2个字符。
如果您的字符串具有非ASCII字符,则将对这些字符进行多字节编码。例如,如果你写
EatMsg: db "Hello Korayğ",10
EatLen: equ $-EatMsg-2这将打印Hello Koray�,因为您没有打印最后一个换行符,也没有打印ğ的最后一个字节,因此您分割成一半的最后一个ğ字符成为无效的UTF-8字符。
编辑:显然,并不是所有的终端都显示�字符,但是您可以通过查看清单文件(nasm的标志�)来查看字符串的编码方式。
https://stackoverflow.com/questions/27847875
复制相似问题