;===============================================================================
SECTION core_data vstart=0 ;系统核心的数据段
;-------------------------------------------------------------------------------
pgdt dw 0 ;用于设置和修改 GDT
dd 0
ram_alloc dd 0x00100000 ;下次分配内存时的起始地址
;符号地址检索表
salt:
salt_1 db '@PrintString'
times 256-($-salt_1) db 0
dd put_string
dw sys_routine_seg_sel
salt_2 db '@ReadDiskData'
times 256-($-salt_2) db 0
dd read_hard_disk_0
dw sys_routine_seg_sel
salt_3 db '@PrintDwordAsHexString'
times 256-($-salt_3) db 0
dd put_hex_dword
dw sys_routine_seg_sel
salt_4 db '@TerminateProgram'
times 256-($-salt_4) db 0
dd return_point
dw core_code_seg_sel
salt_item_len equ $-salt_4
salt_items equ ($-salt)/salt_item_len
如上代码来自书籍 x86 从实模式到保护模式。equ 好像是 NASM 编译器的伪指令。
这是 部分的内核代码,如上是,内核的数据段的描述。 里面有一个符号对应表:每个符号包括三部分:
上面这个salt_items
应该是 4 ,salt_item_len
应该是 256+6=262 。
salt_item_len equ $-salt_4
这一句是可以理解为,计算出了salt_4
标号后面的 db dd dw 的总和吗?但书中原话又说了$-salt_4
是标号 salt_4 的汇编地址,如果是这样,那么这句也是不对的。
salt_items equ ($-salt)/salt_item_len
这一句则完全不理解,除法前面的是salt
,即符号表的基地址,放到这里除 不太对吧?
1
chuckzhou 2022-12-07 09:12:29 +08:00
$ 是变化的,它等于当前地址,$-salt_4 就是当前地址减去 salt_4 的地址,得到的就是一个 item 的大小。
($-salt) 就是整个 salt 占用的空间,除以 salt_item_len 就算出来了一共有几个 salt item 。 equ 就是定义一个符号,不占用空间。 所以这两个 $ 其实相等。 |
2
chrawsl 2022-12-07 09:27:30 +08:00
equ 跟=伪指令大部分时候是一样的,都是用来给一个表达式或者任意文本起一个符号名称,但是在同一源代码文件中,equ 定义的符号不能被重复定义
|
3
chrawsl 2022-12-07 09:30:48 +08:00
$-salt_4 就是当前地址减去 salt_4 的地址,即 salt_4 的长度。下面就是求有多少个 salt 元素,伪指令不会影响 rip ,所以$不改变
|
4
amiwrong123 OP |
5
chrawsl 2022-12-07 12:15:36 +08:00
@amiwrong123 确实跟 #define 一样,就是给特定的表达式起一个别名,编译前会由编译器进行全局替换
|