• NASM网际编译器手册(六)


    NASM,虽然避免象MASM和TASM的官方编译器但也被迫支持一些宏。下面将描述这些内容。
    NASM的定向符有两种类型:用户级的用户定向符和原始级的原始定向符。典型的说,每一个定向符都有一个用户级的和原始级的。在通常情部优下,我们推荐用户使用用户级的,而宏调用原始级的。
    原始级的定向符将用方括号包含;用户级的则无所谓。
    在这章描述的定向符中,每个目标文件格式都能可选的支持外部的定向符,为的是在文件格式中控制得的更
    容易些。这些指定格式的格式定向符将在第六章描述。


    5.1 BITS:指定目标处理模式
    BITS定向符指定了NASM生成的代码是16位处理模式还是32位处理模式的。这个语法分别是BITS16或BIT32。
    在最许多情况下,你不必明确的用BITS。被设计用在32位系统中的aout,coff,elf和win32目标格式,会使NASM来
    选择32位的默认模式。obj目标格式允许你为每一个段指定USE16或USE32,NASM将根据它的操作模式为设置。
    所以人用BITS定向符将不再需要。
    用BITS定向符的主要原因是在一个平坦模式的二进制文件中写一个32位;这是由于二进制的输出格式默认为16
    位模式来为写成DOS和COM的程序准备,DOS的.SYS设备驱动程序 和系统引导程序。
    你在一个16位的DOS程序为了用32位指令而用BITS32为指定生成模式。如果你这样做编译器将会由于生成了
    一个在16位机器上运行32位代码而生成错误的代码。
    当NASM在BITS16下的状态时,用32位的数据用0x66加前缀,而用0x67前缀则表示一个32位的地址。在32位的
    状态时,正好是相反:32位指令不需要前缀,16位数据需要0x66而16位地址则需要0x67。
    BITS有一个等价的原始格式,[BITS 16]和[BITS 32]。用户级格式是一个不能调用原始格式的宏。


    5.2 SECTION或SEGMENT:改变和定义段
    SECTION定向符(SEGMENT是一个等价形式)来改变输出文件的段。在一些目标文件格式,一个数的数量和名
    字是可以修改;可以按照用户的需要来构造宏。如果你想切换到一个来存在段,SECTION将会给出一条错误信息
    或定义一个新段。
    Unix目标格式或二进制目标格式,为代码,数据和非初始化数据段提供.text,.data和.bss段名字。相对来说,目标
    格式不能识别指定的目标段名字并会去掉段名字的引导阶段。


    5.2.1 _SECT_宏
    SECTION定向符与它的原始格式的区别为不常用在用户级的格式。原始格式[SECTION xyz],可以简单的将目标段
    切换到一个给定的段。用户格式SECTION xyz,首先定义了一个单行宏_SECT_来成为一个原始宏[SECTION]定向
    能执行的方式 ,所以用户定向符:
    SECTION .text
    将扩展成
    %define _SECT_[SECTION.text]
    [SECTION.text]
    用户可以发现用它们自己的宏来使用可能很有用。例如,在第4.2.3节中定义的writefile宏将会用下面复杂的格式
    重写:
    %macro writefile 2+
    [section.data]
    %%str: db %2
    %%endstr:
    _SECT_
    mov dx,%%str
    mov cx,%%endstr-%%str
    mov bx,%1
    mov ah,0x40
    int 0x21
    %endmacro
    上面的宏格式交一个字符串传到输出文件,首先将临时切换到文件的数据,用SECTION的原始格式不能修改
    _SECT_。它将在数据段定义字串,然后执行_SECT_切换回先前执行的段。在前一个版本的宏中避免跳过数据段
    为了包含一个JMP指令,在某些方面个复杂的OBJ格式模块中用户可以在不同的代码段中进行汇编。


    5.3 ABSOLUTE:定义绝对标号
    ABSOLUTE定向符是SECTION的一个变化格式:它对一个不直接在物理段的子代码在给定的绝对地址开始。你只
    能在RESB相关指令中使用。ABSOUTE用法如下:
    absolute 0x1a
    kbuf_chr resw 1
    kbuf_free resw 1
    kbuf resw 16
    这个例子描述了一个PC BIOS数据区的段,在段地址为0x40:定义了kbuf_chr为0x1a,kbuf_free为0x1c和kbuf为0x1e。
    ABSOLUTE的用户级格式象SECTION一样,在它被执行时被定义为_SECT_。
    STRUC和ENDSTRUC可以用ABSOLUE(也可以用_SEC_)宏定义。ABSOLUTE不一定带一个绝对的参数:它可以
    带一个表达式(一个临界表达式:见第3.7节)也可以是一个段中的值。例如:一个TSR象运行时的BSS一样重
    用它的setup代码:
    org 100h ;它是一个.COM程序
    jmp setup ;跳到后的设置代码
    ;TSR中的驻留部分
    setup: ;现在写一个安装TSR的代码
    absolute setup
    runtimevar1 resw 1
    runtimevar2 resd 20
    tsr_end:
    在安装代码上定义了一些变量,所以在安装运行完后,它将为运行TSR存储空间来重新放数据。符号\'tsr_end\'
    用来计算TSR的驻留部分的总尺寸。


    5.4 EXTERN:从其它模块中引入符号
    EXTERN与MASM的定向符EXTRN和C语言的关键字extern相似:它被用来引用一个不在模块中定义的符号,但
    在其它模块中定义 了它并且被这个模块引用。不是每一种文件格式都支持引用的变量:bin格式就不支持。
    EXTERN定向符可以带很多参数,每一个参数是一个符号的名字:
    extern _printf
    extern _sscanf,_fscanf
    有一些目标文件格式提供了EXTERN定向符的外部特性。在所有情况下,外部特性用一个后缀的冒号跟在目标
    文件指定文件的符号名。例如目标格式允许你来定义一个默认段的外部基位置 为一个定向符dgroup
    extern _variable:wrt dgroup
    EXTERN的原始格式与它的用户格式的区分为一次只能带一个参数:多个参数的支持在预处理器级上执行。
    你可以用EXTERN多次定义相同的变量 :NASM将会忽略第二个及后面的重定义。你不能用EXTERN定义象
    EXTERN的变量 。


    5.5 GLOBAL:导出符号到其它模块
    GLOBAL是EXTERN的结束标志:如果一个模块用EXTERN定义了一个符号并引用它,为了避免连接器的错误,其
    它的模块必须定义这个标号并用GLOBAL来定义。一些编译器用PUBLIC来支持这个操作。
    GLOBAL定向符必须在符的定义前出现。
    GLOBAL的用法与EXTERN的用法相同,但它必须用在与GLOBAL定向符相同的模块中,例如:
    global _main
    _main: ;一些代码
    GLOBAL,象EXTERN一样允许目标格式定义一个自己的扩展用一个冒号区分,elf目标格式例如 ,可以允许你
    指定全局数据项是functions或data
    global hashlookup:function,hashtable:data
    象EXTERN一样,GLOBAL原始格式与用户级区别为它一次只用一个参数。


    5.6 COMMON:定义常用数据区
    COMMON定向符用来定义一个常用的变量,常用变量可以是一个非初始化数据段的全局变量,如下
    common intvar 4
    与下面功能相似
    global intvar
    section .bss
    intvar resd 1
    不同的是如果多个模块定义了相同的变量,那么在连接时这些变量将合并,在所有模块对这人变量的引用 会
    在内丰中一个指定的位置。

    象GLOBAL和EXTERN,COMMON支持目标格式指定的扩展,例如obj格式允许常用变量为NEAR或FAR而elf格式
    则允许你指定一个常用变量的对齐格式:
    common commvar 4:near ;在OBJ文件中
    ommon intarray 100:4 ;在ELF中:4个字节对齐
    象EXTERN和GLOBAL一样,COMMON的原始格式与用户级格式的区别为它一次只能带一个参数。

  • 相关阅读:
    列表推导式和生成器表达式
    迭代器和生成器
    闭包和装饰器
    函数命名空间和作用域
    华为笔试题06
    华为笔试题05
    华为笔试题04
    华为笔试题03
    华为笔试题02
    华为笔试题01
  • 原文地址:https://www.cnblogs.com/cnlmjer/p/4099881.html
Copyright © 2020-2023  润新知