Skip to content

Commit

Permalink
update markdown format for assembly code
Browse files Browse the repository at this point in the history
  • Loading branch information
Iolop committed Mar 15, 2024
1 parent a5cbc36 commit 25abf8e
Showing 1 changed file with 11 additions and 7 deletions.
18 changes: 11 additions & 7 deletions _posts/2024-03-13-cs-app读书笔记-3-程序的机器级表示.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ gcc是我们之前说的一整套工具,这是Linux上的默认编译器。通

### 汇编代码示例

现在,我们对以下代码,使用 `gcc -Og -S bitset.c`,就会得到一个汇编代码。它的形式和源码有很大的不同,不过我们可以简单一窥其中的对应。
现在,我们对以下代码,使用 `gcc -Og -S bitset_func.c`,就会得到一个汇编代码。它的形式和源码有很大的不同,不过我们可以简单一窥其中的对应。

```c
#include <stdio.h>
Expand All @@ -62,18 +62,19 @@ void set_bit(int *v, int index) {
}
```
```assembly
```
set_bit:
movl $1, %eax
movl %esi, %ecx
sall %cl, %eax
andl %eax, (%rdi)
ret
```
{: file='bitset_func.s'}
同时,如果我们使用 `gcc -Og -c bitset.c`,就会得到二进制格式的文件,这时内容已经基本无法肉眼辨别,这其中有一段序列正是我们在上面看到的汇编代码经过汇编后的形式,为了能得到映射,我们需要使用`objdump -d bitset.o`来观察这个二进制文件。
同时,如果我们使用 `gcc -Og -c bitset_func.c`,就会得到二进制格式的文件,这时内容已经基本无法肉眼辨别,这其中有一段序列正是我们在上面看到的汇编代码经过汇编后的形式,为了能得到映射,我们需要使用`objdump -d bitset_func.o`来观察这个二进制文件。
```assembly
```
Disassembly of section .text:

0000000000000000 <set_bit>:
Expand All @@ -84,6 +85,7 @@ Disassembly of section .text:
d: 21 07 and %eax,(%rdi)
f: c3 ret
```
{: file='bitset_func.o'}
所以说,在二进制程序中,CPU知道的只是一串字节序列,它读取字节序列并且翻译到唯一映射的操作上,关于这种机器码和汇编代码的映射关系,可以查询各架构的ISA,比如x86-64的架构书就在这里[^x86-64ISA]。也许你注意到了一点,这些指令的长度或长或短,这就是复杂指令集的一种特征——不固定长度的指令。
Expand All @@ -99,7 +101,7 @@ int main() {
}
```

```assembly
```
Disassembly of section .text:
0000000000000000 <main>:
0: f3 0f 1e fa endbr64
Expand All @@ -121,12 +123,13 @@ Disassembly of section .text:
44: 48 83 c4 18 add $0x18,%rsp
48: c3 ret
```
{: file='bitset_main.o'}

注意,对比能看到,在进行`set_bit`调用的时候,位置是留空的。因为`call`指令的映射是`0x58`

我们再次使用`gcc -Og -o bitset bitset.c bitset_main.c`。这一次,完成可执行文件的编译、汇编、链接。同样的,使用`objdump -d bitset`来观察编译结果。
我们再次使用`gcc -Og -o bitset bitset_func.c bitset_main.c`。这一次,完成可执行文件的编译、汇编、链接。同样的,使用`objdump -d bitset`来观察编译结果。

```assembly
```
0000000000001149 <main>:
1149: f3 0f 1e fa endbr64
114d: 48 83 ec 18 sub $0x18,%rsp
Expand Down Expand Up @@ -156,6 +159,7 @@ Disassembly of section .text:
11a4: 21 07 and %eax,(%rdi)
11a6: c3 ret
```
{: file='bitset'}

此时,经过了链接的步骤,我们能发现,这里的`bit_set`已经被正确的填入了地址。这再次印证了我们之前提到的步骤:编译、汇编、链接。

Expand Down

0 comments on commit 25abf8e

Please sign in to comment.