0

我有以下汇编代码链接到最终的可执行文件。

section .text
global _start

_start: mov eax, 4
        mov ebx, 1
        mov ecx, mesg
        mov edx, 9
        int 0x80
mesg    db      "Kingkong",0xa

我做的下一件事是得到它的十六进制代码 0xb8,0x04,0x00,0x00,0x00,0xbb,0x01,0x00,0x00,0x00,0xb9,0x76,0x80,0x04,0x08,0xba,0x09,0x00,0x00,0x00,0xcd,0x80,0x4b,0x69,0x6e,0x67,0x6b,0x6f,0x6e,0x67,0x0a

并将其放入另一个程序中,如下所示

section .text
global _start
_start:
        db 0xb8,0x04,0x00,0x00,0x00,0xbb,0x01,0x00,0x00,0x00,0xb9,0x76,0x80,0x04,0x08,0xba,0x09,0x00,0x00,0x00,0xcd,0x80,0x4b,0x69,0x6e,0x67,0x6b,0x6f,0x6e,0x67,0x0a

现在,当我组装上述文件并完成objdump它时,它给了我

08048060 <_start>:
 8048060:       b8 04 00 00 00          mov    $0x4,%eax
 8048065:       bb 01 00 00 00          mov    $0x1,%ebx
 804806a:       b9 76 80 04 08          mov    $0x8048076,%ecx
 804806f:       ba 09 00 00 00          mov    $0x9,%edx
 8048074:       cd 80                   int    $0x80
 8048076:       4b                      dec    %ebx
 8048077:       69 6e 67 6b 6f 6e 67    imul   $0x676e6f6b,0x67(%esi),%ebp
 804807e:       0a                      .byte 0xa

mesg最终转储中没有看到标签,那么程序如何找出mesg上述程序中段的地址?

编辑: 好吧,我想在阅读答案后对此添加一个小问题,我可以理解标签不用于实际寻址,而是直接将地址烘焙到代码中,但是如果指定地址,mov $0x8048076,%ecx那么保证是什么下次加载程序时,它将完全从同一个地址开始......如果我用 C 包装这段代码怎么办?如果我想在另一台具有完全不同内存模式的机器上运行它怎么办?

4

2 回答 2

4

标签被转换为偏移量/地址。除非您明确保留该信息以进行调试,否则您不会看到实际的标签。

该行:

mov    $0x8048076, %ecx

基本上有 的值mesg,即地址0x8048076,也是字符串的开头Kingkong

程序不需要“弄清楚” 的值mesg是什么,因为它甚至不知道有什么叫做mesg. 它所看到的只是一个地址,这很好,因为这就是它所需要的。

使用命名标签很方便,并且有助于提高可读性。它们仅对汇编器和链接器真正重要,因为它们会将标签的值转换为其实际地址或偏移量。调试器也可以使用它(如果您指示汇编器或链接器保留调试信息)来帮助您调试代码。

要解决您的第二个问题:

您拥有的地址是虚拟内存地址(即,它们不是物理内存地址)。这意味着您的可执行文件实际上并不需要知道它将位于哪个物理地址,因为操作系统会在运行时将其映射到正确的位置(即物理内存中)。这就是为什么如果您在另一台机器上运行可执行文件(假设已为该操作系统编译可执行文件)或重复运行它,您的可执行文件将工作的原因。操作系统负责将该虚拟地址映射到物理内存。

您可以在这里这里查看更多信息。

于 2013-08-06T17:43:50.477 回答
2

最终转储中没有看到mesg标签,那么程序如何找出上述程序中mesg段的地址?

标签只对汇编器和链接器(和调试器)有意义。它们将被最终机器代码中的分配地址替换(如果需要重新定位可执行文件,则可能会在运行时更改)。

正如您在反汇编中看到的那样,ecx加载了 address 0x8048076。在反汇编中的那个地址,我们找到了 bytes 4b 69 6e 67 ...,它对应于字符 'K'、'i'、'n'、'g'。换句话说; ecx现在指向你的mesg字符串的开头。

于 2013-08-06T17:46:06.667 回答