使用$ - x时,我们在汇编中减去多少位(或字节)

时间:2015-01-08 19:18:12

标签: linux ubuntu assembly encoding

这是我的源代码:

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

1 个答案:

答案 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)来查看字符串的编码方式