- 首先看一下一段操作系统内核加载的源代码
%include "boot.inc" ; 导入自己写的宏文件
section loader vstart=LOADER_BASE_ADDR ; 指明该段段内汇编的起始地址,值为0x900
LOADER_STACK_TOP equ LOADER_BASE_ADDR
jmp start ; 汇编语言是同时编译,顺序执行,但是下面的初始化也已经写入了内存中
; 定义三个GDT描述符,第0个无效初始化为0
; dd表示四个字节,一个字节是8个二进制位数
GDT_START: dd 0x00000000
dd 0x00000000
; 根据段选择子位功能进行的拼凑
CODE_DESC: dd 0x0000FFFF
dd DESC_CODE_HIGH4
STACK_DATA_DESC: dd 0x0000FFFF
dd DESC_DATA_HIGH4
VIDIO_DESC: dd 0x80000007
dd DESC_VIDEO_HIGH4
GDT_SIZE equ $-GDT_START ; 当前地址-GDT起始地址是GDT的范围
GDT_LIMIT equ GDT_SIZE-1 ; -1转化成物理地址
times 60 dq 0 ; dp是8个字节,申请60个8字节的空间并初始化为0
- 在虚拟机bochs中运行,使用x指令查看逻辑内存的值
- 解释
- vatart表明了汇编语言转换后的逻辑起始段地址是0x900
- x 0x900:查看0x900出内存后4个字节的值,其中e9表示jmp跳转指令的二进制编码,并且其后4个字节表示其跳转的地址
- x 0x904:0~4中五个字节表示jmp start在内存中的二进制编码,0x904后面表示了第一个段描述符的内容,一个段描述符是8个字节
- x 0x90B:表示第二个段描述符中的内容,即0x904+8
- 总结,汇编语言编译成二进制,是顺序存储的(可能存在编译器的优化和伪指令的过滤),
指令和数据都是统一存储在内存单元的二进制
,该汇编程序中jmp不会跳过开辟内存存储数据的dd指令,而是在内存中顺序存放指令数据,指令和数据的差别由CPU执行的指令决定