汇编程序如何工作?

use*_*906 7 assembly linker object machine-code

我正在寻找使用汇编程序生成机器代码的简要说明.

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

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

mat*_*tja 11

汇编程序和编译器都将源文件转换为目标文件.

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

链接器获取指定的目标文件和库(它们是目标文件包)并解析重定位(或"fixup")记录.

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

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

main.asm:

bits 64
section .text
extern do_message
global _start
_start:
    call do_message
    mov rax, 1
    int 0x80 
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

如果你组装它们并查看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
Run Code Online (Sandbox Code Playgroud)

但是,对地址的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
Run Code Online (Sandbox Code Playgroud)

偏移量为"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
Run Code Online (Sandbox Code Playgroud)

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