宏观编译对应的微观编译步骤:
对应步骤如下:
编译:
预编译 : 展开头文件和宏定义
编译compile : main.c -> main.s arm-linux-gcc -S main.c
汇编assembly: main.s -> main.o arm-linux-as -o main.o main.s
链接link : main.o -> main(elf) arm-linux-ld main.o -o main
生成二进制文件: main -> main.bin查看反汇编命令
./aarch64-linux-gnu-objdump -S main -a arm -C
现列举几个做实验的文件:
main.c main.h display.c display.h
目的是想要通过一个makefile实现是这几个文件的编译管理
main.c:
#include "display.h"
int main(int argc, char *argv[])
{
display();
return 0;
}
int test_read(){ return 0; }
int test_write(){ return 0; }
main.h
#ifndef _MAIN_H_
#define _MAIN_H_
int test_read();
int test_write();
#endif
display.c
#include "display.h"
void display()
{
printf("======================\n");
printf("==r==read opt ========\n");
printf("==w==write opt========\n");
printf("==q==quit opt ========\n");
}
display.h
#ifndef _DISPLY_H_
#define _DISPLY_H_
void display();
#endif
正常一两个文件我们直接在目录下执行
gcc main.c display.c -o main 直接执行就可以了
如果文件较多并且只更新一个或几个文件来编译就要用makefile
CC := gcc #声明一个变量
src_o := main.o display.o #声明变量表示所有 .o 汇编后的中间文件.PHONY :all #声明一个伪目标
all: main #
main : $(src_o) #目标为 main 依赖于 main.o display.o
$(CC) -o $@ $^ #翻一下就是 gcc -o main main.o display.o%.o : %.c #匹配%.o 匹配%.c
$(CC) -c $< # gcc -c main.c ; gcc -c display.c
.PHONY :clean
clean:
rm *.o main -f
解释三个变量: $@ $< $^
$@ : 表示目标
$^: 表示所有依赖
$<: 表示第一个依赖
%.o : %.c #匹配%.o 匹配%.c
$(CC) -c $< # gcc -c main.c ; gcc -c display.c
%.c 有多个 main.c 和 display.c 因此匹配后%.o 也有多个
这个 $(CC) -c $< 就会执行多次, 分别是gcc -c main.c 和gcc -c display.c
我的实验环境是使用xilinx zcu102 开发板:
编译:
aarch64-linux-gnu-gcc -S main.c
aarch64-linux-gnu-gcc -S display.c
aarch64-linux-gnu-as main.s -o main.o
aarch64-linux-gnu-as display.s -odisplay.o
aarch64-linux-gnu-ld main.o display.o -o main
aarch64-linux-gnu-objdump -S main -C
最后有个报错: 因为没有指定入口,GNU汇编文件一般都是_start: 为入口, 给分配了默认起始执行地址,也可以添加lds指定。
形式如下:
.globl _start:
_start:
b reset
.....