最小的程序
#include <stdio.h>
// #include "/dev/urandom" to stuck some Online Judge
int main() {
printf("hello world\n");
}
gcc main.c
file a.out
a.out: Mach-O 64-bit executable x86_64
objdump -d a.out
a.out: file format mach-o 64-bit x86-64
Disassembly of section __TEXT,__text:
0000000100000f70 <_main>:
100000f70: 55 pushq %rbp
100000f71: 48 89 e5 movq %rsp, %rbp
100000f74: 48 83 ec 10 subq $16, %rsp
100000f78: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
100000f7f: 48 8d 3d 15 00 00 00 leaq 21(%rip), %rdi ## 0x100000f9b <_printf+0x100000f9b>
100000f86: b0 00 movb $0, %al
100000f88: e8 08 00 00 00 callq 0x100000f95 <_printf+0x100000f95>
100000f8d: 31 c0 xorl %eax, %eax
100000f8f: 48 83 c4 10 addq $16, %rsp
100000f93: 5d popq %rbp
100000f94: c3 retq
Disassembly of section __TEXT,__stubs:
0000000100000f95 <__stubs>:
100000f95: ff 25 65 00 00 00 jmpq *101(%rip) ## 0x100001000 <_printf+0x100001000>
readelf -a a.out | less
// in GNU Linux
本机为macxOS ,无法执行
gcc main.c -static
不知为何,在macxOS没有执行成功
file a.out
objdump -d a.out
gcc –verbose main.c
Apple clang version 15.0.0 (clang-1500.3.9.4)
Target: x86_64-apple-darwin23.4.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
"/Library/Developer/CommandLineTools/usr/bin/clang" -cc1 -triple x86_64-apple-macosx14.0.0 -Wundef-prefix=TARGET_OS_ -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -emit-obj -mrelax-all --mrelax-relocations -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.c -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fno-strict-return -ffp-contract=on -fno-rounding-math -funwind-tables=2 -target-sdk-version=14.4 -fvisibility-inlines-hidden-static-local-var -target-cpu penryn -tune-cpu generic -debugger-tuning=lldb -target-linker-version 1053.12 -v -fcoverage-compilation-dir=/Users/morningcat/Documents/CLionProjects/study163-weng -resource-dir /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -I/usr/local/include -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include -internal-isystem /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/include -internal-externc-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -internal-externc-isystem /Library/Developer/CommandLineTools/usr/include -Wno-reorder-init-list -Wno-implicit-int-float-conversion -Wno-c99-designator -Wno-final-dtor-non-final-class -Wno-extra-semi-stmt -Wno-misleading-indentation -Wno-quoted-include-in-framework-header -Wno-implicit-fallthrough -Wno-enum-enum-conversion -Wno-enum-float-conversion -Wno-elaborated-enum-base -Wno-reserved-identifier -Wno-gnu-folding-constant -fdebug-compilation-dir=/Users/morningcat/Documents/CLionProjects/study163-weng -ferror-limit 19 -stack-protector 1 -fstack-check -mdarwin-stkchk-strong-link -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fmax-type-align=16 -fcommon -fcolor-diagnostics -clang-vendor-feature=+disableNonDependentMemberExprInCurrentInstantiation -fno-odr-hash-protocols -clang-vendor-feature=+enableAggressiveVLAFolding -clang-vendor-feature=+revert09abecef7bbf -clang-vendor-feature=+thisNoAlignAttr -clang-vendor-feature=+thisNoNullAttr -mllvm -disable-aligned-alloc-awareness=1 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /var/folders/3w/715mdb1n6blbf3kh68zf53bh0000gn/T/main-500b9a.o -x c main.c
clang -cc1 version 15.0.0 (clang-1500.3.9.4) default target x86_64-apple-darwin23.4.0
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include"
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/include
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
/Library/Developer/CommandLineTools/usr/include
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.
"/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -lto_library /Library/Developer/CommandLineTools/usr/lib/libLTO.dylib -no_deduplicate -dynamic -arch x86_64 -platform_version macos 14.0.0 14.4 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -o a.out -L/usr/local/lib /var/folders/3w/715mdb1n6blbf3kh68zf53bh0000gn/T/main-500b9a.o -lSystem /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/lib/darwin/libclang_rt.osx.a
gcc -Wl,–verbose main.c // in GUN Linux
gcc -Wl,-v main.c // in macxOS
@(#)PROGRAM:ld PROJECT:ld-1053.12
BUILD 15:44:24 Feb 3 2024
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
will use ld-classic for: armv6 armv7 armv7s arm64_32 i386 armv6m armv7k armv7m armv7em
LTO support using: LLVM version 15.0.0 (static support for 29, runtime is 29)
TAPI support using: Apple TAPI version 15.0.0 (tapi-1500.3.2.2)
Library search paths:
/usr/local/lib
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/swift
Framework search paths:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks
解决异常退出
程序自己是不能 “停下来” 的
只能借助操作系统
movq $SYS_exit, %rax # exit(
movq $1, %rdi # status=1
syscall # );
把 “系统调用” 的参数放到寄存器中
执行 syscall,操作系统接管程序 操作系统可以任意改变程序状态 (甚至终止程序)
syscall 指令
什么是Linux系统调用
or https://linux.die.net/man/2/syscall or https://man.archlinux.org/man/syscall.2.en
Linux有哪些系统调用
接着探讨最小的程序
// https://www.huii.top/938.html
#include <sys/syscall.h>
#define syscall3(id, a1, a2, a3) \
movq $SYS_##id, %rax; \
movq $a1, %rdi; \
movq $a2, %rsi; \
movq $a3, %rdx; \
syscall
#define syscall1(id, a1) syscall3(id, a1, 0, 0)
.globl _start
_start:
syscall3(write, 1, addr1, addr2 - addr1)
syscall1(exit, 1)
addr1:
.ascii "\033[01;31mHello, world\033[0m\n"
addr2:
gcc -g -S main.s > minimal.s
.globl _start
_start:
movq $4, %rax; movq $1, %rdi; movq $addr1, %rsi; movq $addr2 - addr1, %rdx; syscall
movq $1, %rax; movq $1, %rdi; movq $0, %rsi; movq $0, %rdx; syscall
addr1:
.ascii "\033[01;31mHello, world\033[0m\n"
addr2:
as minimal.s -o minimal.o
ld -o minimal minimal.o
./minimal
CPU架构
GNU/Linux
cat /proc/version
uname -a
file /bin/bash
arch
aarch64, arm64 – ARM架构
x86_64,x64,AMD64 – X86架构
mips – MIPS架构
另一种实现
#include <sys/syscall.h>
.globl _start
_start:
movq $SYS_write, %rax // write(
movq $1, %rdi // fd=1,
movq $st, %rsi // buf=st,
movq $(ed - st), %rdx // count=ed-st
syscall // );
movq $SYS_exit, %rax // exit(
movq $1, %rdi // status=1
syscall // );
st:
.ascii "\033[01;31mHello, OS World\033[0m\n"
ed:
gcc -c minimal.s
ld minimal.o
objdump -d a.out wc -l
WSL Ubuntu下的实践
hello.s
.section .data
msg: .ascii "Hello World\n"
.section .text
.global _start
_start:
mov $1, %rax
mov $1, %rdi
mov $msg, %rsi
mov $12, %rdx
syscall
mov $60, %rax
xor %rdi, %rdi
syscall
gcc -c hello.s
ld hello.o -o hello
./hello
8500+5100+3400-481.87-380-1113.82^_^202404-15024.31
另一个实践成功的案例
.globl _start
_start:
movq $1, %rax // write(
movq $1, %rdi // fd=1,
movq $st, %rsi // buf=st,
movq $(ed - st), %rdx // count=ed-st
syscall // );
movq $60, %rax // exit(
movq $1, %rdi // status=1
syscall // );
st:
.ascii "\033[01;31mHello World\033[0m\n"
ed:
gcc -c my.s
ld my.o -o my