Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Object 汇编程序是如何工作的?_Object_Assembly_Linker_Machine Code - Fatal编程技术网

Object 汇编程序是如何工作的?

Object 汇编程序是如何工作的?,object,assembly,linker,machine-code,Object,Assembly,Linker,Machine Code,我正在寻找一个简短的描述使用汇编在生产机器代码 所以我知道汇编是机器代码的1:1翻译。但我对目标代码和链接器以及它们是如何放入其中的感到困惑 我不需要复杂的答案,一个简单的答案就可以了,汇编程序和编译器都可以将源文件翻译成目标文件 对象文件实际上是最终可执行输出(由链接器生成)之前的中间步骤 链接器获取指定的对象文件和库(它们是对象文件包)并解析重定位(或“修复”)记录 当编译器/汇编器不知道源代码中使用的函数或变量的地址,并按名称为其生成引用(可由链接器解析)时,会生成这些重定位记录 例如,假

我正在寻找一个简短的描述使用汇编在生产机器代码

所以我知道汇编是机器代码的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 
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,这是无效的

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
偏移量为“1”,类型为“R_X86_64_PC32”,它告诉链接器解析此引用,并将解析的地址放入指定的偏移量中

当您将最后一个程序与'ld-o program main.o message.o'链接时,所有重定位都已解决,如果没有未解决的问题,您将得到一个可执行文件

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

$ 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
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
0000000000 4000F0:
4000f0:e8 0b 00 00 00 callq 400100
4000f5:48 c7 C001 00 mov$0x1,%rax
4000fc:cd 80整数$0x80
同样的重新定位也用于变量和函数。 当您将程序链接到多个大型库(如libc)时,也会发生相同的过程-您定义了一个名为“main”的函数,libc有一个外部引用-然后libc在程序之前启动,并在运行可执行文件时调用“main”函数。

简单解释:


一旦汇编语言被汇编成目标代码,链接器就被用来将目标代码转换成计算机可以理解和运行的命令的可执行文件。生成的机器代码可以由cpu的控制器解释。

asm->object->linking。。。你能解释一下为什么目标文件中的偏移量是一,以及如何计算吗?抱歉,这是一个愚蠢的问题。@gavlaaaaaaaa:main.o中do_消息重定位引用的偏移量是1,因为代码从0开始,偏移量0是操作码“e8”,它是指令“callq”,偏移量1是下一个32位值的开始,它是“callq”指令的操作数。