zoukankan      html  css  js  c++  java
  • 先熟悉nasm 【4】 ——SECTION和标签

       1,nasm下,自定义段默认按4byte对齐。

      手册上说,“ 通过在段定义行的后面加上'ALIGN'限定符实现的。比如:section .data align=16 它切换到段'.data',并指定它必须对齐到 16 字节边界。”    我也在自定义段里加上align 16,发现编译生成的代码仍按照4byte对齐。很诡异。


      2,再说标签。

      看下面一段代码(可正常运行),它们被写到mbr,会被加载到0x7c00处

    ----------------------------

    org 0h

    s:mov ax,s

    inc ax

    .....

    ---------------------------

      问:编译器会怎么处理标签s呢?是将其翻译成真实的物理地址,还是偏移地址呢?

      要回答这个问题,只需要将编译后的二进制文件反汇编,看看mov ax,s这句便可,下面是我在bochs上的反汇编结果:

    ----------------------------------------------------------------------------

    00007c00: (                    ): mov ax, 0x0000            ; b80000

    ----------------------------------------------------------------------------

      mov ax,s被翻译成mov ax, 0x0000。显然,编译器处理标签时,是将标签翻译成对应的“偏移地址”——有人要问了,你这“偏移地址”说的不明不白的,究竟是相对哪儿的偏移地址呢?是相对于源代码的第一条指令的偏移么?   这就得提到org指令了,当org的操作数是0,这“偏移地址”就是相对于程序开头儿第一条指令,若org的操作数是个非0常数xx,这“偏移地址”就要额外的加上xx。方便理解,这里再举个例子,将上面的代码变一下:

    ----------------------------

    org 10h

    s:mov ax,s

    inc ax

    .....

    ---------------------------

      反汇编可看到:

    -----------------------------------------------------------------------------

    0000:7c00 (unk. ctxt): mov ax, 0x0010            ; b81000
    ----------------------------------------------------------------------------

      因此得到结论:标签被翻译成“偏移地址”。


      3,$和$$是特殊的标签:$$表示当前section第一行的相对“偏移地址”,$表示当前行的相对“偏移地址”。举个小例子,看代码:

    -----------------------------

    %include "./rw_floppy.mac"
    org 7c00h
    entrance:read_floppy_side_o_sector_total_destsa_destea 0,0,0,2,30,0,7e00h   ;这是我自己定义的宏,负责将第二个扇区的代码加载到0x0000:0x7e00处。
    jmp main_entrance
    times 510-($-$$) db 0
    dw 0aa55h                                                                                                                             ;第一个扇区填满
    main_entrance:                                                                                                                     ;此处代码从第二个扇区开始
    [SECTION .test1 ]
    mov ax,$
    mov ax,$
    mov ax,$$
    mov ax,$$
    [SECTION .test2]
    mov ax,$
    mov ax,$
    mov ax,$$
    mov ax,$$

    ----------------------------

    看反汇编后的结果:

    ------------------------------

    00007e00: (                    ): mov ax, 0x7e00            ; b8007e
    00007e03: (                    ): mov ax, 0x7e03            ; b8037e
    00007e06: (                    ): mov ax, 0x7e00            ; b8007e
    00007e09: (                    ): mov ax, 0x7e00            ; b8007e
    00007e0c: (                    ): mov ax, 0x7e0c            ; b80c7e
    00007e0f: (                    ): mov ax, 0x7e0f            ; b80f7e
    00007e12: (                    ): mov ax, 0x7e0c            ; b80c7e
    00007e15: (                    ): mov ax, 0x7e0c            ; b80c7e

    -----------------------------

    不用多说,结果非常清楚了


    4,发现一个问题:nasm中不能跨段执行标签的减法运算。看代码:

    ---------------------------

    org 7c00h
    entrance:read_floppy_side_o_sector_total_destsa_destea 0,0,0,2,30,0,7e00h
    jmp main_entrance
    times 510-($-$$) db 0
    dw 0aa55h
    main_entrance:
    [SECTION .test1 ]
    s1:db 0
    [SECTION .test2]
    s2:db 0
    s3:mov ax,s3-s1                         ;注意这儿,s1和s3是不同SECTION的标签
    --------------------------

    上面代码不能通过编译,会报错error: invalid operand type

    但下面代码就可以通过编译:

    ---------------------------

    org 7c00h
    entrance:read_floppy_side_o_sector_total_destsa_destea 0,0,0,2,30,0,7e00h
    jmp main_entrance
    times 510-($-$$) db 0
    dw 0aa55h
    main_entrance:
    [SECTION .test1 ]
    s1:db 0
    [SECTION .test2]
    s2:db 0
    s3:mov ax,s3-s2                        ;注意这儿,s2和s3是相同SECTION的标签
    --------------------------

    我猜测是nasm禁止跨段做标签的减法,不知道有没有朋友也遇到此情况。


    2012,8,25    吉首

     

  • 相关阅读:
    array and ram
    char as int
    pointer of 2d array and address
    Install SAP HANA EXPRESS on Google Cloud Platform
    Ubuntu remount hard drive
    Compile OpenSSL with Visual Studio 2019
    Install Jupyter notebook and tensorflow on Ubuntu 18.04
    Build OpenCV text(OCR) module on windows with Visual Studio 2019
    Reinstall VirtualBox 6.0 on Ubuntu 18.04
    Pitfall in std::vector<cv::Mat>
  • 原文地址:https://www.cnblogs.com/weiweishuo/p/3082641.html
Copyright © 2011-2022 走看看