
;=============================================================================== 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 Dec 7, 2022 $ 是变化的,它等于当前地址,$-alt_4 就是当前地址减去 salt_4 的地址,得到的就是一个 item 的大小。 ($-salt) 就是整个 salt 占用的空间,除以 salt_item_len 就算出来了一共有几个 salt item 。 equ 就是定义一个符号,不占用空间。 所以这两个 $ 其实相等。 |
2 chrawsl Dec 7, 2022 equ 跟=伪指令大部分时候是一样的,都是用来给一个表达式或者任意文本起一个符号名称,但是在同一源代码文件中,equ 定义的符号不能被重复定义 |
3 chrawsl Dec 7, 2022 $-salt_4 就是当前地址减去 salt_4 的地址,即 salt_4 的长度。下面就是求有多少个 salt 元素,伪指令不会影响 rip ,所以$不改变 |
4 amiwrong123 OP |
5 chrawsl Dec 7, 2022 @amiwrong123 确实跟 #define 一样,就是给特定的表达式起一个别名,编译前会由编译器进行全局替换 |