[toc]

GCC编译器的基本使用

gcc的编译过程

  1. 预处理。
1
gcc -E main.c -o main.i
  1. 编译。用编译器将预处理代码转换为汇编代码
1
gcc -S main.i -o main.s
  1. 汇编。用汇编器将汇编代码转换为机器码,产生的文件叫做目标文件
1
2
gcc -c main.s -o main.o
#as -c main.s -o main.o
  1. 链接。链接过程使用链接器将该目标文件与其他目标文件、库文件、启动文件等链接起来生成可执行文件
1
2
gcc main.o -o main
#ld main.o -o main

GCC编译器编译c++

gcc/g++ 编译c/cpp的区别(十分啰嗦,十分详细)

1
gcc -s main.cpp -o main.exe -lstdc++

mingw64位编译32位c程序命令

1
gcc -m32 main.c -o main.out

gcc编译32位c++程序命令

1
gcc -m32 test.cpp -o test.out

gcc编译64位c++程序命令

1
gcc -m64 test.cpp -o test.out

报错的话需要安装相关库

1
2
3
4
#For C language:
sudo apt-get install gcc-multilib
#For C++ language:
sudo apt-get install g++-multilib

How to compile 32-bit program on 64-bit gcc in C and C++

静态编译命令

1
-static-libstdc++ -static-libgcc

gcc编译裸机程序

1
2
3
4
5
6
#编译
gcc -ffreestanding -c function.c -o function.o
#gcc -c function.c -o function.o
#链接
ld -o function.bin -Ttext 0x0 --oformat binary function.o
#ld -o function.bin function.o

16位实模式汇编程序

1
2
3
4
5
6
7
8
9
10
#汇编
as --32 code16.s -o code16.o
#链接
ld -Ttext 0x100 -m elf_i386 code16.o -o code16.elf
#转换
objcopy -j .text -O binary code16.elf code16.com
#8086反汇编
objdump -d -m i8086 code16.elf
#binary反汇编
objdump -D -m i8086 -b binary code16.com

gcc内连汇编

1
2
#指定intel格式
gcc -masm=intel test.c -o test

GCC编译动态库

生成动态库文件

1
gcc --shared func.c -o libfunc.so

动态库编译进代码

1
2
3
4
gcc main.c -lfunc -L. -o main
# -lfunc 是指定的依赖动态库名称func
# -L. 是指定动态库的路径
# . 当前路径

GCC编译静态库

生成静态库

1
2
3
4
#生成目标代码
gcc -c func.c -o func.o
# 打包静态库
ar -r libfunc.a func.o

将静态库编译进代码

1
gcc libfunc.a main.c -L. -o main

mingw中的汇编命令用法

将c语言源码转为汇编源码

1
gcc  -O2 -S main.c -m32 -fno-omit-frame-pointer

汇编器(assembler)汇编 AT&T 格式的源代码:

1
as -c main.s -o main.o

相关链接:

汇编语言–Linux 汇编语言开发指南

Archived | Linux assemblers: A comparison of GAS and NASM

gcc生成intel语法的汇编代码

1
2
3
gcc -S -masm=intel test.c
gcc -O2 -S -masm=intel test.c -m32 -fno-omit-frame-pointer
gcc -S -fno-asynchronous-unwind-tables -masm=intel test.c

汇编命令

1
2
3
4
#gcc -s test.s -o test.o
#nasm -f elf test.s
as test.s -o test.o
gcc test.o -o test

NASM汇编器

NASM使用的是 Intel 的汇编格式:

1
$ nasm -f elf hello.asm

使用NASM汇编代码

1
2
3
4
5
nasm -f win64 file.s
#it generate obj file

link file.obj
#VC++ link the obj,generate exe file

使用以下命令将汇编代码编译成可执行文件:

1
2
nasm -f elf64 nasm.asm -o nasm.o
ld nasm.o -o nasm

NASM将汇编代码生成为二进制文件

1
2
#NASM汇编为bin文件
nasm exam.asm -f bin -o exam.bin

NASM里的ndisasm工具将二进制代码反汇编

1
ndisasm -b 32 function.bin

格式转换与反汇编工具

objcopy

使用objcopy工具可以将可执行文件转换为二进制文件,可以使用以下命令

1
objcopy -O binary program.exe program.bin

​ 目标文件转为二进制文件

1
2
3
4
5
6
7
8
9
10
11
12
#obj转化为bin
objcopy -O binary asm.obj asm.bin
#bin转化为hex
objcopy -I binary -O ihex asm.bin asm.hex
#hex文件转化为bin
objcopy -I ihex -O binary asm.hex asm.bin
#bin转换elf
objcopy -I binary -O elf32-i386 -B i386 asm.bin asm.elf


#linux查看二进制代码
hexdump -C hello.bin

objdump

objdump查看a.o的代码段

1
2
3
4
5
objdump -d a.o
objdump -d -j .text hello
#intel语法
objdump -M intel -d asm.exe > a.txt

gdb

gdb反汇编代码

1
2
3
4
5
6
7
8
9
#运行gdb
gdb asm.exe
#设置为intel语法
set disassembly-flavor intel
#运行程序
file asm.exe
#反汇编main函数
disassemble main

将gdb的输出信息存到文件的方法

1
2
3
4
set logging file a.txt
set logging on
disassemble main
set logging off

一些其他工具

od#

另一个十分常用的工具是 od。该工具提供 -x 参数用于输出十六进制的文件原始数据。

1
2
3
$ od -x file1
0000000 6577 636c 6d6f 0a65
0000010

同样,为了让输出更加易读,可使用 -c 参数输出文本。

1
2
3
4
$ od -xc file1
0000000 6577 636c 6d6f 0a65
w e l c o m e \n
0000010

xxd#

xxd 是一个稍特殊的工具,它还提供了一个 -r 选项,可将十六进制信息转换回原始文件,可用于编辑 Hex 内容。

1
2
$ xxd file1
0000000: 7765 6c63 6f6d 650a welcome.

假设我们有 file2 文件,内容如下:

1
2
$ cat file2
000000: 7765 6c63 6f6d 650a

那么我们可以使用 -r 选项来将其转换为原文件内容:

1
2
$ xxd -r file2
welcome

vs2019编译器

命令行使用ml命令调用ml.exe程序编译汇编程序

打开vs2019控制台x64

切换汇编程序目录

编译命令

1
2
3
4
5
ml64 /c  /Cp message.asm #生成obj文件

ml64.exe message.asm /link /subsystem:console /entry:main

ml64.exe message.asm /link /subsystem:console /defaultlib:kernel32.lib /entry:main

ML 和 ML64 命令行参考

链接器选项