gpt4 book ai didi

object - 汇编程序如何工作?

转载 作者:行者123 更新时间:2023-12-03 06:27:47 25 4
gpt4 key购买 nike

我正在寻找有关如何使用汇编器生成机器代码的简要说明。

所以我知道汇编是机器代码的 1:1 翻译。但我对目标代码和链接器以及它们如何放入其中感到困惑。

我不需要复杂的答案,只要一个简单的答案就可以了

最佳答案

汇编器和编译器都将源文件翻译成目标文件。

目标文件实际上是最终可执行输出(由链接器生成)之前的中间步骤。

链接器获取指定的目标文件和库(它们是目标文件的包)并解析重定位(或“修复”)记录。

当编译器/汇编器不知道源代码中使用的函数或变量的地址时,会生成这些重定位记录,并按名称生成对其的引用,该引用可以由链接器解析。

例如,假设您希望程序将一条消息打印到屏幕上,分为两个源文件,并且您希望单独组装它们并链接它们(例如使用 Linux x86-64 系统调用) -

main.asm:

bits 64
section .text
extern do_message
global _start
_start:
call do_message
mov rax, 1
int 0x80

消息.asm:

bits 64
section .text
global do_message
do_message:
mov rdi, message
mov rcx, dword -1
xor rax, rax
repnz scasb
sub rdi, message
mov rax, 4
mov rbx, 1
mov rcx, message
mov rdx, rdi
int 0x80
ret

section .data
message: db "hello world",10,0

如果您组装这些并查看 main.asm 的目标文件输出(例如 objdump -d main.o),您会注意到“call do_message”的地址为 00 00 00 00 - 这是无效的。

0000000000000000 <_start>:
0: e8 00 00 00 00 callq 5 <_start+0x5>
5: 48 c7 c0 01 00 00 00 mov $0x1,%rax
c: cd 80 int $0x80

但是,对地址的4个字节做了重定位记录:

$ objdump -r main.o
main.o: file format elf64-x86-64
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000000000001 R_X86_64_PC32 do_message+0xfffffffffffffffc
000000000000000d R_X86_64_32 .data

偏移量为“1”,类型为“R_X86_64_PC32”,告诉链接器解析此引用,并将解析后的地址放入指定的偏移量中。

当您将最终程序与“ld -o program main.o message.o”链接时,所有重定位都已解决,如果没有任何问题未解决,则留下可执行文件。

当我们“objdump -d”可执行文件时,我们可以看到解析的地址:

00000000004000f0 <_start>:
4000f0: e8 0b 00 00 00 callq 400100 <do_message>
4000f5: 48 c7 c0 01 00 00 00 mov $0x1,%rax
4000fc: cd 80 int $0x80

相同类型的重定位用于变量和函数。当您将程序链接到多个大型库(例如 libc)时,会发生相同的过程 - 您定义一个名为“main”的函数,libc 有一个外部引用 - 然后 libc 在您的程序之前启动,并在以下情况下调用您的“main”函数您运行可执行文件。

关于object - 汇编程序如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6167208/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com