CSAPP Notes ML Programming

0xfffffff / 2023-08-23 / 原文

CSAPP Notes: ML Programming

Computer System - Notes: ML Programming

本课程主要使用 x86 指令;CISC(复杂指令集);

ARM 属于 RISC (精简指令集);

g++gcc

g++gcc 都是 GNU Compiler Collection(GNU 编译器集合)中的工具,用于编译源代码并生成可执行文件。然而,它们之间有一些区别:

  1. g++:
    • g++ 是 GNU 编译器集合中专门用于编译 C++ 源代码的工具。
    • 当你使用 g++ 编译时,它会默认将源代码视为 C++ 代码,然后应用 C++ 相关的语法和标准库。
    • 如果你使用 g++ 编译一个 C++ 源文件,它会自动链接 C++ 标准库。
    • 例如:g++ main.cpp -o main
  2. gcc:
    • gcc 是 GNU 编译器集合中通用的编译器,可以用于编译多种编程语言,包括 C、C++、Objective-C 等。
    • 当你使用 gcc 编译时,它会根据文件的扩展名来确定是 C 还是 C++ 代码。.c 扩展名会被视为 C 代码,.cpp 扩展名会被视为 C++ 代码。
    • 对于 C++ 代码,gcc 会自动调用 g++ 来处理。
    • 如果你使用 gcc 编译 C++ 源文件,同样会链接 C++ 标准库。
    • 例如:gcc main.cpp -o main

流程

  1. 预处理阶段(Preprocessing):
    • 输入:.cpp.h 等源文件。
    • 输出:.i 文件。
    • 过程:在此阶段,预处理器执行宏展开、文件包含等操作,生成一个经过预处理的源代码文件。
  2. 编译阶段(Compilation):
    • 输入:.i 文件。
    • 输出:.s 文件。
    • 过程:编译器将经过预处理的源代码翻译成汇编语言代码。
  3. 汇编阶段(Assembly):
    • 输入:.s 文件。
    • 输出:.o 文件。
    • 过程:汇编器将汇编语言代码翻译成机器代码,并生成目标文件(.o 文件)。
  4. 链接阶段(Linking):
    • 输入:.o 文件、库文件等。
    • 输出:可执行文件(通常无后缀名,或 .exe.out 等,取决于操作系统)。
    • 过程:链接器将目标文件以及可能的库文件链接在一起,解决符号引用,生成最终的可执行文件。

常用参数

  1. 编译参数:

    • g++ source.cpp:编译 source.cpp 文件并生成默认输出文件 a.out
    • g++ source.cpp -o output:编译 source.cpp 文件并将可执行文件命名为 output
  2. 指定编译阶段:

    • -c:只进行编译,不进行链接,生成目标文件(.o 文件)。
      • 预处理->编译->汇编
    • -S:只进行预处理和编译,不进行汇编和链接,生成汇编代码文件(.s 文件)。
      • 预处理->编译
    • -E:只进行预处理,不进行编译等等,生成的仍然是.cpp 文件;
  3. 预处理选项:

    • -E:只进行预处理,将预处理结果输出到标准输出。
  4. 优化选项:

    • -O0-O1-O2-O3:指定不同级别的优化。-O0 表示不进行优化,-O3 表示最高级别优化。

    • https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

      优化级别:

      1. -O0: 这是最低级别的优化,代码将不会进行任何优化处理。这对于调试和分析非常有用,因为生成的代码将与源代码相匹配,但可能会导致较低的性能。
      2. -O1: 这个级别启用了一些基本的优化,如去除冗余的计算和一些常见的性能改进。代码的执行速度可能会稍有提升,但仍然保持着较好的调试友好性。
      3. -O2: 在这个级别,编译器会执行更多的优化,包括内联函数、循环展开等。这会带来显著的性能提升,但有些情况下可能会导致一些调试信息的丢失。
      4. -O3: 这是更高级别的优化,编译器会进行更多的变换,以提高代码的执行速度。然而,这可能会导致一些副作用,如增加代码大小和编译时间。
      5. -Os: 该选项会优化代码的大小,即尽量减小生成的可执行文件的大小,而不是追求最大的性能提升。
      6. -Og: 此选项用于 "优化用于调试",会在保留调试信息的前提下,进行一些基本的优化,以平衡调试友好性和性能。
      7. -Ofast: 这是一个极高级别的优化选项,会启用所有的优化,并可能会违反一些标准的语义,以实现更高的性能。但这可能会导致一些不符合预期的行为。
  5. 链接选项:

    • -l<library>:链接指定的库。例如,-lm 链接数学库。
    • -L<dir>:指定搜索库文件的目录。
  6. 头文件包含路径:

    • -I<dir>:指定头文件的搜索路径。
  7. 其他常用选项:

    • -std=<standard>:指定使用的 C++ 标准,例如 -std=c++11
    • -Wall:开启所有警告信息。
    • -g:生成调试信息,用于调试程序。
    • -Werror:将警告视为错误。
    • -pedantic:严格遵循标准规范,发出更多警告。

程序清单

#include <iostream>

using namespace std;
int main() {
    cout << "Hello world!" << endl;
    int x = 1;
    int y = 2;
    int z = 3;

    return 0;
}

  • -c:只进行编译,不进行链接,生成目标文件(.o 文件)。

    • 预处理->编译->汇编

    • g++ test.cpp -Og -c

    • 可以用 objdump 或者 nm 等工具查看目标文件

      • objdump -d test.o   # 查看目标文件的汇编代码
        nm test.o           # 列出目标文件中的符号表信息
        
  • -S:只进行预处理和编译,不进行汇编和链接,生成汇编代码文件(.s 文件)。

    • 预处理->编译
    • g++ test.cpp -Og -S (生成一个 600 行左右的汇编代码)
  • -E:只进行预处理,不进行编译等等,生成的仍然是.cpp 文件;

    • 预处理
    • g++ test.cpp -Og -E -o test.pre (会变成一个六万行左右的cpp代码)
    • 预处理会进行一些操作,比如:
      • 宏展开
      • 头文件包含
      • 条件编译
      • 删除注释
      • 生成行号信息
    • 大体上可以理解为 copy and paste

Assembly

Disassembling Object Code: Disassembler

objdump -d ___

> g++ --version

Apple clang version 14.0.3 (clang-1403.0.22.14.1)

Target: arm64-apple-darwin22.6.0

Thread model: posix

InstalledDir: /Library/Developer/CommandLineTools/usr/bin

到汇编就停下:

g++ test.cpp -Og -S
	.section	__TEXT,__text,regular,pure_instructions
	.build_version macos, 13, 0	sdk_version 13, 3
	.globl	__Z6my_sumii                    ; -- Begin function _Z6my_sumii
	.p2align	2
__Z6my_sumii:                           ; @_Z6my_sumii
	.cfi_startproc
; %bb.0:
	add	w0, w1, w0
	ret
	.cfi_endproc
                                        ; -- End function
	.globl	_main                           ; -- Begin function main
	.p2align	2
_main:                                  ; @main
	.cfi_startproc
; %bb.0:
	mov	w0, #0
	ret
	.cfi_endproc
                                        ; -- End function
.subsections_via_symbols

先生成可执行文件,再反汇编

g++ test.cpp -Og -o test.o
`objdump -d test >> test.txt`	

test.o:	file format mach-o arm64

Disassembly of section __TEXT,__text:

0000000100003fa8 <__Z6my_sumii>:
100003fa8: 20 00 00 0b 	add	w0, w1, w0
100003fac: c0 03 5f d6 	ret

0000000100003fb0 <_main>:
100003fb0: 00 00 80 52 	mov	w0, #0
100003fb4: c0 03 5f d6 	ret

可以看到生成的汇编代码会短一点,因为丢失了一些信息;

等下,这个课程用的是 x86 的汇编()

换个机器先——

> g++ --version

g++ (GCC) 8.3.1 20190311 (Red Hat 8.3.1-3)

Copyright (C) 2018 Free Software Foundation, Inc.

This is free software; see the source for copying conditions. There is NO

warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.