如何理解汇编伪指令 equ 的使用? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
请不要在回答技术问题时复制粘贴 AI 生成的内容
amiwrong123

如何理解汇编伪指令 equ 的使用?

  •  
  •   amiwrong123 Dec 6, 2022 1403 views
    This topic created in 1237 days ago, the information mentioned may be changed or developed.
    ;=============================================================================== 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 。

    1. salt_item_len equ $-salt_4这一句是可以理解为,计算出了salt_4标号后面的 db dd dw 的总和吗?但书中原话又说了$-salt_4是标号 salt_4 的汇编地址,如果是这样,那么这句也是不对的。

    2. salt_items equ ($-salt)/salt_item_len这一句则完全不理解,除法前面的是salt,即符号表的基地址,放到这里除 不太对吧?

    Supplement 1    Dec 7, 2022
    可能我这个标题起的不对,也许和这个伪指令 equ 没有关系。
    正确的标题应该是:如何正确使用汇编里面的标号。
    5 replies    2022-12-07 12:15:36 +08:00
    chuckzhou
        1
    chuckzhou  
       Dec 7, 2022
    $ 是变化的,它等于当前地址,$-alt_4 就是当前地址减去 salt_4 的地址,得到的就是一个 item 的大小。
    ($-salt) 就是整个 salt 占用的空间,除以 salt_item_len 就算出来了一共有几个 salt item 。
    equ 就是定义一个符号,不占用空间。
    所以这两个 $ 其实相等。
    chrawsl
        2
    chrawsl  
       Dec 7, 2022
    equ 跟=伪指令大部分时候是一样的,都是用来给一个表达式或者任意文本起一个符号名称,但是在同一源代码文件中,equ 定义的符号不能被重复定义
    chrawsl
        3
    chrawsl  
       Dec 7, 2022
    $-salt_4 就是当前地址减去 salt_4 的地址,即 salt_4 的长度。下面就是求有多少个 salt 元素,伪指令不会影响 rip ,所以$不改变
    amiwrong123
        4
    amiwrong123  
    OP
       Dec 7, 2022
    @chuckzhou #1
    @chrawsl #3
    OK ,理解了。所以说,标号的话,就是代表的是 变量的起始地址。
    而$就是当前地址。

    而且,我理解,那这个 equ 的一条汇编地址,感觉就和“C 语言里面#define” 一样,在实际编译出来的二进制不存在这条指令。

    而且,进一步理解的话,那既然带 equ 的指令实际上不存在,那是不是说,在带 equ 的汇编指令里 使用符号$,其实是指 下一条不带 equ 的标号的地址(因为我代码没有给全,所以这条指令在帖子中 没有)。
    chrawsl
        5
    chrawsl  
       Dec 7, 2022
    @amiwrong123 确实跟 #define 一样,就是给特定的表达式起一个别名,编译前会由编译器进行全局替换
    About     Help     Advertise     Blog     API     FAQ     Solana     4128 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 04:14 PVG 12:14 LAX 21:14 JFK 00:14
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86