C++ 在区分源代码、目标代码、汇编代码和机器代码时,我感到困惑
我阅读我们编写源代码(高级语言)的每个地方,编译器将其转换为机器代码(低级语言)。然后我读到有一个汇编程序,它将汇编代码转换成机器代码。然后在区分编译器和解释器时,我读到编译器首先将整个代码转换为目标代码,而解释器通过跳过目标代码直接转换为机器代码。现在我有了困惑,我想到了以下问题:C++ 在区分源代码、目标代码、汇编代码和机器代码时,我感到困惑,c++,assembly,interpreter,low-level,high-level,C++,Assembly,Interpreter,Low Level,High Level,我阅读我们编写源代码(高级语言)的每个地方,编译器将其转换为机器代码(低级语言)。然后我读到有一个汇编程序,它将汇编代码转换成机器代码。然后在区分编译器和解释器时,我读到编译器首先将整个代码转换为目标代码,而解释器通过跳过目标代码直接转换为机器代码。现在我有了困惑,我想到了以下问题: 编译器是否直接将源代码转换为机器代码 目标代码和机器代码的区别是什么 谁将源代码转换为汇编代码 什么是高级语言和低级语言,如何区分它们 汇编代码和目标代码是高级还是低级 除了源代码之外,所有的语言都是低级语言 我相
除了源代码之外,所有的语言都是低级语言 我相信对象和机器代码指的是同一件事 由于源代码通常直接转换为机器代码,所以不存在从源代码到汇编代码的直接转换。汇编程序可用于将汇编代码转换为机器代码(汇编语言与机器代码的对应关系为1:1)。编译器用于将源代码直接转换为机器代码 使用汇编程序是因为,由于每种类型的计算机的机器代码不同,汇编语言也特定于每种类型的计算机 高级语言是我们使用抽象的低级语言编写易于阅读和理解的代码的语言。它是一个抽象概念,帮助我们在编码时提高效率
低级语言是指很少或根本没有从计算机指令集中抽象出来的语言。大多数问题都没有简单的答案,因为不同的编译器可能会有所不同。一些编译器发出其他高级语言,如C
-v
选项一起使用的命令链。例如,对于C源代码
int main(){return 1;}
命令汇编程序采用汇编语言,即人类易于读写的处理器指令,并将其转换为机器代码或这些指令的二进制版本 汇编语言向量
.thumb
.globl _start
_start:
.word 0x20001000
.word reset
.word foo
.word foo
.word foo
.word foo
.word foo
.word foo
.thumb_func
reset:
bl fun
.thumb_func
foo:
b foo
.globl dummy
dummy:
bx lr
组装然后拆卸
arm-none-eabi-as vectors.s -o vectors.o
arm-none-eabi-objdump -D vectors.o > vectors.list
拆卸的相关部分
Disassembly of section .text:
00000000 <_start>:
0: 20001000
...
00000020 <reset>:
20: f7ff fffe bl 0 <fun>
00000024 <foo>:
24: e7fe b.n 24 <foo>
00000026 <dummy>:
26: 4770 bx lr
Disassembly of section .text:
00000000 <fun>:
0: e59f200c ldr r2, [pc, #12] ; 14 <fun+0x14>
4: e5923000 ldr r3, [r2]
8: e2833005 add r3, r3, #5
c: e5823000 str r3, [r2]
10: e12fff1e bx lr
14: 00000000 andeq r0, r0, r0
编撰
arm-none-eabi-gcc -mthumb -save-temps -O2 -c fun.c -o fun.o
arm-none-eabi-objdump -D fun.o > fun.list
第一个temp是预处理器,它接受#defines和#include并基本上去除它们,生成将发送给编译器的文件
# 1 "fun.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "fun.c"
unsigned int more_fun ( unsigned int );
void fun ( void )
{
more_fun(5);
}
然后调用汇编器将其转换为一个对象,我们可以在这里的对象分解中看到生成的内容:
Disassembly of section .text:
00000000 <fun>:
0: b508 push {r3, lr}
2: 2005 movs r0, #5
4: f7ff fffe bl 0 <more_fun>
8: bc08 pop {r3}
a: bc01 pop {r0}
c: 4700 bx r0
e: 46c0 nop ; (mov r8, r8)
编译器输入
# 1 "more_fun.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "more_fun.c"
unsigned int more_fun ( unsigned int x )
{
return(x+1);
}
对象的反汇编(汇编程序输出)
不再使用太多,但并非完全无用,过去需要这种格式来编程rom,工具制造商个人偏好他们支持的文件格式。二进制文件是如何在微控制器中烧成闪存的?一些工具从主机/开发机器上获取这些位,并通过一些接口和一些软件将其移动到目标,该工具支持什么二进制文件格式?取决于编写工具的人选择一种或多种格式
在编译器以各种方式(购买成本和/或在计算机上保存程序的存储空间,加上中间数据等)都可以负担得起之前,汇编程序可以用来生成整个程序。您可以看到像.org 100h这样的指令,通过“工具链”,汇编程序可能具有该功能,但作为该链的一部分,汇编程序工具需要从汇编语言转换为对象格式,大部分转换为机器代码和其他数据。当然,当工具链的一部分sane方法最终从源代码到汇编语言时,编译器可能完成所有工作并输出完成的二进制文件。我们使用的编译器工具,gcc、msvc、clang等,除非告诉我们不要太多,否则将为我们生成汇编程序和链接器以及编译器,使编译器看起来像是在一个神奇的步骤中从源代码到最终二进制代码。链接器获取具有未解析外部标签的单个对象,并决定它们在内存映像中的位置,在内存中的位置,根据需要解析外部。链接器的功能是这些工具系统设计的重要组成部分,设计可以使链接器不修改单个指令,而只将地址放在约定的位置。例如:
向量
.thumb
.globl _start
_start:
.word 0x20001000
.word reset
.word foo
.word foo
.word foo
.word foo
.word foo
.word foo
.thumb_func
reset:
bl fun
.thumb_func
foo:
b foo
.globl dummy
dummy:
bx lr
.globl _start
_start:
bl fun
b .
.global hello
hello: .word 0
乐趣
有趣的拆卸
Disassembly of section .text:
00000000 <_start>:
0: 20001000
...
00000020 <reset>:
20: f7ff fffe bl 0 <fun>
00000024 <foo>:
24: e7fe b.n 24 <foo>
00000026 <dummy>:
26: 4770 bx lr
Disassembly of section .text:
00000000 <fun>:
0: e59f200c ldr r2, [pc, #12] ; 14 <fun+0x14>
4: e5923000 ldr r3, [r2]
8: e2833005 add r3, r3, #5
c: e5823000 str r3, [r2]
10: e12fff1e bx lr
14: 00000000 andeq r0, r0, r0
链接二进制的反汇编
00002000 <_start>:
2000: f000 f812 bl 2028 <__fun_from_thumb>
2004: e7fe b.n 2004 <_start+0x4>
00002006 <hello>:
2006: 00000000 andeq r0, r0, r0
...
0000200c <fun>:
200c: e59f200c ldr r2, [pc, #12] ; 2020 <fun+0x14>
2010: e5923000 ldr r3, [r2]
2014: e2833005 add r3, r3, #5
2018: e5823000 str r3, [r2]
201c: e12fff1e bx lr
2020: 00002006 andeq r2, r0, r6
2024: 00000000 andeq r0, r0, r0
00002028 <__fun_from_thumb>:
2028: 4778 bx pc
202a: 46c0 nop ; (mov r8, r8)
202c: eafffff6 b 200c <fun>
000020000:
2000:f000 f812 bl 2028
2004年:e7fe b.n 2004
00002006 :
2006年:00000000安第克r0,r0,r0
...
0000200c:
200c:e59f200c ldr r2,[pc,#12];2020
2010年:e5923000 ldr r3[r2]
arm-none-eabi-ld -Ttext=0x2000 vectors.o fun.o more_fun.o -o run.elf
arm-none-eabi-objdump -D run.elf > run.list
arm-none-eabi-objcopy -O srec run.elf run.srec
Disassembly of section .text:
00002000 <_start>:
2000: 20001000
2004: 00002021
2008: 00002025
200c: 00002025
2010: 00002025
2014: 00002025
2018: 00002025
201c: 00002025
00002020 <reset>:
2020: f000 f802 bl 2028 <fun>
00002024 <foo>:
2024: e7fe b.n 2024 <foo>
00002026 <dummy>:
2026: 4770 bx lr
00002028 <fun>:
2028: b508 push {r3, lr}
202a: 2005 movs r0, #5
202c: f000 f804 bl 2038 <more_fun>
2030: bc08 pop {r3}
2032: bc01 pop {r0}
2034: 4700 bx r0
2036: 46c0 nop ; (mov r8, r8)
00002038 <more_fun>:
2038: 3001 adds r0, #1
203a: 4770 bx lr
4: f7ff fffe bl 0 <more_fun>
202c: f000 f804 bl 2038 <more_fun>
S00B000072756E2E73726563C4
S113200000100020212000002520000025200000D1
S113201025200000252000002520000025200000A8
S113202000F002F8FEE7704708B5052000F004F858
S10F203008BC01BC0047C04601307047EA
S9032000DC
.globl _start
_start:
bl fun
b .
.global hello
hello: .word 0
#define FIVE 5
extern unsigned int hello;
void fun ( void )
{
hello+=FIVE;
}
Disassembly of section .text:
00000000 <fun>:
0: e59f200c ldr r2, [pc, #12] ; 14 <fun+0x14>
4: e5923000 ldr r3, [r2]
8: e2833005 add r3, r3, #5
c: e5823000 str r3, [r2]
10: e12fff1e bx lr
14: 00000000 andeq r0, r0, r0
Disassembly of section .text:
00002000 <_start>:
2000: eb000001 bl 200c <fun>
2004: eafffffe b 2004 <_start+0x4>
00002008 <hello>:
2008: 00000000 andeq r0, r0, r0
0000200c <fun>:
200c: e59f200c ldr r2, [pc, #12] ; 2020 <fun+0x14>
2010: e5923000 ldr r3, [r2]
2014: e2833005 add r3, r3, #5
2018: e5823000 str r3, [r2]
201c: e12fff1e bx lr
2020: 00002008 andeq r2, r0, r8
.thumb
.globl _start
_start:
bl fun
b .
.global hello
hello: .word 0
#define FIVE 5
extern unsigned int hello;
void fun ( void )
{
hello+=FIVE;
}
00002000 <_start>:
2000: f000 f812 bl 2028 <__fun_from_thumb>
2004: e7fe b.n 2004 <_start+0x4>
00002006 <hello>:
2006: 00000000 andeq r0, r0, r0
...
0000200c <fun>:
200c: e59f200c ldr r2, [pc, #12] ; 2020 <fun+0x14>
2010: e5923000 ldr r3, [r2]
2014: e2833005 add r3, r3, #5
2018: e5823000 str r3, [r2]
201c: e12fff1e bx lr
2020: 00002006 andeq r2, r0, r6
2024: 00000000 andeq r0, r0, r0
00002028 <__fun_from_thumb>:
2028: 4778 bx pc
202a: 46c0 nop ; (mov r8, r8)
202c: eafffff6 b 200c <fun>