这更多是一个概念性问题,但是我正在为即将进行的项目学习嵌入式系统。我一直在浏览有关教程的教程。
https://www.tutorialspoint.com/embedded_systems/es_tools.htm
此网页讨论编译器,汇编器和耦合。
基本上:汇编过程如何与编译器一起工作。我在哪里以及如何分割这些信息?我没有得到什么?
答案 0 :(得分:1)
使用gnu工具自己尝试
#define FIVE 5
extern unsigned int more_fun ( unsigned int );
unsigned int fun ( void )
{
return(more_fun(FIVE)+1);
}
保存临时文件gcc首先需要进行预处理以引入包含并替换定义/宏
# 1 "so.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "so.c"
extern unsigned int more_fun ( unsigned int );
unsigned int fun ( void )
{
return(more_fun(5)+1);
}
被送入实际编译器的,gcc程序不是编译器,而是一个调用其他程序的程序。编译器输出是汇编语言
.arch armv5t
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 2
.eabi_attribute 34, 0
.eabi_attribute 18, 4
.file "so.c"
.text
.align 2
.global fun
.syntax unified
.arm
.type fun, %function
fun:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
push {r4, lr}
mov r0, #5
bl more_fun
add r0, r0, #1
pop {r4, pc}
.size fun, .-fun
.ident "GCC: (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609"
.section .note.GNU-stack,"",%progbits
然后gcc调用汇编程序以将其汇编为一个对象。这是汇编程序可以解析的尽可能多的机器代码,以及理想情况下用于调试和链接的其他信息。使用反汇编程序,我们可以看到由汇编程序生成的代码:
Disassembly of section .text:
00000000 <fun>:
0: e92d4010 push {r4, lr}
4: e3a00005 mov r0, #5
8: ebfffffe bl 0 <more_fun>
c: e2800001 add r0, r0, #1
10: e8bd8010 pop {r4, pc}
中间的bl 0调用的解析未解决,因为该代码不是原始C源文件的一部分,因此在其中放置了占位符,链接器将在以后出现。 ...这些物体在一起。如果您未指定-c,则gcc还将为您调用链接器。
大多数“工具链”都是以这种方式工作的,这是理智的方式。出于及时和“为什么要爬山,因为那里的原因”的原因,有些编译器更直接地使用机器代码,但是llvm也不这样做,它声称是JIT,尽管其主要用途是JIT。工具链不必使用单独的可执行文件,也无需使用各种方法来解决问题。
我不记得您链接的站点是否应不惜一切代价避免出现在站点列表中,有一个或多个类似的站点包含一些非常糟糕的信息,这些信息令人困惑和错误。该页面既不错也不混乱,但是我只是略读了一下。
反编译器并不真正以人们想编译的形式存在,正如您在此简单示例中看到的那样,原始代码中的信息丢失了,您无法从二进制文件中完全重新创建此代码。制作类似的简单示例来演示这一点很容易。