如何解决汇编程序如何工作?
| 我正在寻找有关在生成机器代码中使用汇编程序的简要说明。 所以我知道汇编是机器代码的1:1翻译。但是我对目标代码和链接器以及它们如何放置在其中感到困惑。 我不需要复杂的答案,只需一个简单的答案就可以了解决方法
汇编器和编译器都将源文件转换为目标文件。
目标文件实际上是最终可执行输出(由链接器生成)之前的中间步骤。
链接器获取指定的目标文件和库(它们是目标文件的包),并解析重定位(或\'fixup \')记录。
当编译器/汇编器不知道源代码中使用的函数或变量的地址时,便会创建这些重定位记录,并按名称为其生成引用,链接器可以解析该引用。
例如,假设您要一个程序将消息打印到屏幕上,并分成两个源文件,并且要分别汇编它们并链接它们(例如,使用Linux x86-64 syscalls)-
main.asm:
bits 64
section .text
extern do_message
global _start
_start:
call do_message
mov rax,1
int 0x80
message.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 \'函数,当您运行可执行文件时。
, 简单说明:
一旦将汇编语言汇编成目标代码,链接器便会用于将目标代码转换为计算机可以理解和运行的命令的可执行文件。生成的机器代码可由CPU的控制器解释。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。