├── README.md ├── chapter12 └── 1.asm ├── chapter13 ├── c13.asm ├── c13_core.asm └── 修改点.md ├── chapter14 └── 1 │ ├── c13.asm │ └── 修改点.md ├── chapter3 └── 1.asm ├── chapter8 ├── 1 │ └── 1.md └── 2 │ └── c08.asm ├── chapter9 ├── 1.asm ├── c09_1_1.asm └── c09_1_2.asm ├── images ├── 12_1_memory_option.png ├── 12_1_result.png ├── bochs_config_1.png ├── bochs_config_2.png ├── bochs_config_3.png ├── bochs_config_4.png ├── chapter8_1.png ├── disk_create.png └── floppy_create.png └── 实验方法.md /README.md: -------------------------------------------------------------------------------- 1 | # X86_ASM 2 | 3 | ## 12.1 4 | 5 | 程序将在界面的左上角(即1行1列开始)实时显示已检测的字节数,如果检测失败,那么将在第二行显示fail字样: 6 | 7 | ![12章检测1](images/12_1_result.png) 8 | 9 | 注意,这里并不是因为真的失败而显示fail,原因是:代码中的检测次数写死为: 10 | 11 | ```assembly 12 | ;每次检测4B,所以总共需要检测(4GB - 1MB) / 4 次 13 | mov eax, 1073479680 14 | ``` 15 | 16 | 但是在我的机器上Bochs的默认内存大小是: 17 | 18 | ![内存大小](images/12_1_memory_option.png) 19 | 20 | 即32MB,所以实际最大可检测的大小为: 21 | (32 - 1) * 1024 * 1024 = 32505856, 22 | 23 | 此数字与上面实验结果完全吻合,说明实验正确。😀 -------------------------------------------------------------------------------- /chapter12/1.asm: -------------------------------------------------------------------------------- 1 | ;设置堆栈段和栈指针 2 | mov eax,cs 3 | mov ss,eax 4 | mov sp,0x7c00 5 | 6 | ;计算GDT所在的逻辑段地址 7 | mov eax,[cs:pgdt+0x7c00+0x02] ;GDT的32位线性基地址 8 | xor edx,edx 9 | mov ebx,16 10 | div ebx ;分解成16位逻辑地址 11 | 12 | mov ds,eax ;令DS指向该段以进行操作 13 | mov ebx,edx ;段内起始偏移地址 14 | 15 | ;创建0#描述符,它是空描述符,这是处理器的要求 16 | mov dword [ebx+0x00],0x00000000 17 | mov dword [ebx+0x04],0x00000000 18 | 19 | ;1#描述符,数据段,1MB~4GB的线性地址空间 20 | mov dword [ebx+0x08],0x0000ffff 21 | mov dword [ebx+0x0c],0x00cf9210 22 | 23 | ;创建保护模式下初始代码段描述符 24 | mov dword [ebx+0x10],0x7c0001ff ;基地址为0x00007c00,512字节 25 | mov dword [ebx+0x14],0x00409800 ;粒度为1个字节,代码段描述符 26 | 27 | ;显存段 28 | mov dword [ebx + 0x18], 0x80008000 29 | mov dword [ebx + 0x1c], 0x0040920b 30 | 31 | ;初始化描述符表寄存器GDTR 32 | mov word [cs: pgdt+0x7c00], 31 33 | 34 | lgdt [cs: pgdt+0x7c00] 35 | 36 | in al,0x92 ;南桥芯片内的端口 37 | or al,0000_0010B 38 | out 0x92,al ;打开A20 39 | 40 | cli ;中断机制尚未工作 41 | 42 | mov eax,cr0 43 | or eax,1 44 | mov cr0,eax ;设置PE位 45 | 46 | ;以下进入保护模式... ... 47 | jmp dword 0x0010:check ;16位的描述符选择子:32位偏移 48 | 49 | [bits 32] 50 | check: 51 | mov eax,0x0008 52 | mov ds, eax 53 | mov eax, 0x18 54 | mov es, eax 55 | 56 | ;每次检测4B,所以总共需要检测(4GB - 1MB) / 4 次 57 | mov eax, 1073479680 58 | mov ecx, eax 59 | 60 | ;每次检测的内存地址 61 | xor ebx, ebx 62 | 63 | @1: mov dword [ebx], 0x55AA55AA 64 | mov eax, [ebx] 65 | cmp eax, 0x55AA55AA 66 | jne fail 67 | 68 | mov dword [ebx], 0xAA55AA55 69 | mov eax, [ebx] 70 | cmp eax, 0xAA55AA55 71 | jne fail 72 | 73 | ;当前双字检测成功 74 | add ebx, 4 75 | ;累加检测数量 76 | mov eax, ebx 77 | call show_checked 78 | 79 | loop @1 80 | 81 | ;检测成功 82 | jmp done 83 | 84 | fail: ;检测失败,显示错误信息 85 | mov byte [es:160], 'f' 86 | mov byte [es:162], 'a' 87 | mov byte [es:164], 'i' 88 | mov byte [es:166], 'l' 89 | 90 | done: hlt 91 | 92 | ; 子程序: 显示已经检查的字节数 93 | show_checked: push edx 94 | push esi 95 | push ecx 96 | 97 | xor edx, edx 98 | xor ecx, ecx 99 | mov esi, 10 100 | 101 | @2: div esi 102 | ; 保存余数用于显示 103 | push edx 104 | inc ecx 105 | xor edx, edx 106 | 107 | cmp eax, 0 108 | je @3 109 | 110 | jmp @2 111 | 112 | @3: xor esi, esi 113 | @4: pop edx 114 | add edx, 48 115 | mov [es:esi], dl 116 | add esi, 2 117 | loop @4 118 | 119 | pop ecx 120 | pop esi 121 | pop edx 122 | 123 | ret 124 | 125 | ;------------------------------------------------------------------------------- 126 | pgdt dw 0 127 | dd 0x00007e00 ;GDT的物理地址 128 | ;------------------------------------------------------------------------------- 129 | times 510-($-$$) db 0 130 | db 0x55,0xaa -------------------------------------------------------------------------------- /chapter13/c13.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/chapter13/c13.asm -------------------------------------------------------------------------------- /chapter13/c13_core.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/chapter13/c13_core.asm -------------------------------------------------------------------------------- /chapter13/修改点.md: -------------------------------------------------------------------------------- 1 | # 修改点 2 | 3 | 1. c13_core.asm: 第462-471行,用户程序栈段的重定位方式。 4 | 2. c13.asm: 第13-14,39-46行,栈段的定义。 -------------------------------------------------------------------------------- /chapter14/1/c13.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/chapter14/1/c13.asm -------------------------------------------------------------------------------- /chapter14/1/修改点.md: -------------------------------------------------------------------------------- 1 | 仅需将c13.asm第86行的返回调用由jmp改为call即可: 2 | 3 | ```assembly 4 | call far [fs:TerminateProgram] ;将控制权返回到系统 5 | ``` 6 | 7 | 这将会导致特权级的改变。 -------------------------------------------------------------------------------- /chapter3/1.asm: -------------------------------------------------------------------------------- 1 | mov ax, 0x3f 2 | add bx, ax 3 | add cx, ax -------------------------------------------------------------------------------- /chapter8/1/1.md: -------------------------------------------------------------------------------- 1 | 本实验其实就是简单的将作者的代码运行起来,如下图: 2 | 3 | ![运行结果](../images/chapter8_1.png) -------------------------------------------------------------------------------- /chapter8/2/c08.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/chapter8/2/c08.asm -------------------------------------------------------------------------------- /chapter9/1.asm: -------------------------------------------------------------------------------- 1 | sti 2 | 3 | cli 4 | 5 | times 510 - ($ - $$) db 0 6 | dw 0xaa55 -------------------------------------------------------------------------------- /chapter9/c09_1_1.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/chapter9/c09_1_1.asm -------------------------------------------------------------------------------- /chapter9/c09_1_2.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/chapter9/c09_1_2.asm -------------------------------------------------------------------------------- /images/12_1_memory_option.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/images/12_1_memory_option.png -------------------------------------------------------------------------------- /images/12_1_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/images/12_1_result.png -------------------------------------------------------------------------------- /images/bochs_config_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/images/bochs_config_1.png -------------------------------------------------------------------------------- /images/bochs_config_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/images/bochs_config_2.png -------------------------------------------------------------------------------- /images/bochs_config_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/images/bochs_config_3.png -------------------------------------------------------------------------------- /images/bochs_config_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/images/bochs_config_4.png -------------------------------------------------------------------------------- /images/chapter8_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/images/chapter8_1.png -------------------------------------------------------------------------------- /images/disk_create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/images/disk_create.png -------------------------------------------------------------------------------- /images/floppy_create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seaswalker/X86_ASM/dbf68df2f382a181fca6136ac83577eb8283e2f6/images/floppy_create.png -------------------------------------------------------------------------------- /实验方法.md: -------------------------------------------------------------------------------- 1 | # 实验方法 2 | 3 | 从第8章开始,使用书中所说的VirtualBox已经无法完成正常的实验(反应为无法启动),所以改为Bochs的方式,这里参考了: [硬盘和显卡的访问与控制](https://www.kancloud.cn/digest/protectedmode/121456)一文。 4 | 5 | ## 启动软盘 6 | 7 | 以第8章为例,我们将启动(mbr)程序写入到一个软盘中,创建软盘可以使用Bochs自带的bximage工具,方法很简单,如下图: 8 | 9 | ![软盘创建](images/floppy_create.png) 10 | 11 | 然后使用Linux命令(这里用的是Windows 10 Linux子系统): 12 | 13 | ```shell 14 | dd if=c08_mbr.bin of=boot.img 15 | ``` 16 | 17 | boot.img便是我们新创建的1.44MB软盘。 18 | 19 | ## 硬盘 20 | 21 | 我们的主程序写入到一个硬盘中,同样使用bximage工具来完成创建,如下图: 22 | 23 | ![硬盘创建](images/disk_create.png) 24 | 25 | 然后同样使用dd命令将编译得到的c08.bin写入到硬盘中: 26 | 27 | ```shell 28 | dd if=c08.bin of=c.img bs=512 seek=100 conv=notrunc 29 | ``` 30 | 31 | ## Bochs配置 32 | 33 | 首先在主界面选择Disk & Boot进行配置,如下: 34 | 35 | ![启动设置](images/bochs_config_1.png) 36 | 37 | ### 软盘 38 | 39 | ![软盘设置](images/bochs_config_2.png) 40 | 41 | ### 硬盘 42 | 43 | ![硬盘设置](images/bochs_config_3.png) 44 | 45 | 解释一下红色方框处的三个参数的意义: 46 | 47 | 1. Cylinders: 柱面 48 | 2. Heads: 磁头 49 | 3. Sectors per track(SPT): 扇区数 50 | 51 | 当我们完成硬盘创建时,bximage工具会告诉我们这些参数,如下图: 52 | 53 | ![硬盘参数](images/bochs_config_4.png) 54 | 55 | Have fun! 😄 --------------------------------------------------------------------------------