OS

操作系统课程2024-02

应用视角的操作系统

Posted by BY morningcat on May 8, 2024

最小的程序

#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系统调用

man 2 syscall

or https://linux.die.net/man/2/syscall or https://man.archlinux.org/man/syscall.2.en

Linux有哪些系统调用

man 2 syscalls

接着探讨最小的程序

// 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

做减法:把 “不重要” 的部分屏蔽掉

system call trace (strace)