首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

GNU汇编总结 08

GNU汇编总结 08

九,使用函数
   
    ################################################################################################
   
    GNU汇编语言定义函数的语法:
   
    .type 标签(也就是函数名), @function
   
    ret    返回到调用处
   
    ################################################################################################
   
    # 十,linux系统调用
   
    ################################################################################################
   
    linux系统调用的中断向量为0x80
   
    1, 系统调用标识存放在%eax中
   
    2, 系统调用输入值:
   
    EBX     第一个参数
   
    ECX     第二个参数
   
    EDX     第三个参数
   
    ESI     第四个参数
   
    EDI     第五个参数
   
    需要输入超过6个输入参数的系统调用, EBX指针用于保存指向输入参数内存位置的指针, 输入参数按照连续的的顺序
   
    存储, 系统调用的返回值存放在EAX中
   
    ################################################################################################
   
    # 十一,汇编语言的高级功能
   
    ################################################################################################
   
    1,gnu内联汇编的语法:
   
    asm或__asm__("汇编代码");
   
    指令必须包含在引号里
   
    如果包含的指令超过一行 必须使用新行分隔符分隔
   
    使用c全局变量, 不能在内联汇编中使用局部变量, 注意在汇编语言代码中值被用做内存位置, 而不是立即数值
   
    如果不希望优化内联汇编, 则可以volatile修饰符如:__asm__ volatile("code");
   
    2,GCC内联汇编的扩展语法
   
    __asm__("assembly code"utput locations:input operands:changed registers);
   
    第一部分是汇编代码
   
    第二部分是输出位置, 包含内联汇编代码的输出值的寄存器和内存位置列表
   
    第三部分是输入操作数,包含内联汇编代码输入值的寄存器和内存位置的列表
   
    第四部分是改动的寄存器, 内联汇编改变的任何其他寄存器的列表
   
    这几个部分可以不全有, 但是没有的还必须使用:分隔
   
    1, 指定输入值和输出值, 输入值和输出值的列表格式为:
   
    "constraint"(variable), 其中variable是程序中声明的c变量, 在扩展asm格式中, 局部和全局变量都可以使用,
   
    使用constrant(约束)定义把变量存放到哪(输入)或从哪里传送变量(输出)
   
    约束使用单一的字符, 如下:
   
    约束                                   描述
   
    a                         使用%eax, %ax, %al寄存器
   
    b                         使用%ebx, %bx, %bl寄存器
   
    c                         使用%ecx, %cx, %cl寄存器
   
    d                         使用%edx, %dx, %dl寄存器
   
    S                         使用%esi, %si寄存器
   
    D                         使用%edi, %di寄存器
   
    r                         使用任何可用的通用寄存器
   
    q                         使用%eax, %ebx, %ecx,%edx之一
   
    A                         对于64位值使用%eax, %edx寄存器
   
    f                         使用浮点寄存器
   
    t                         使用第一个(顶部)的浮点寄存器
   
    u                         使用第二个浮点寄存器
   
    m                         使用变量的内存位置
   
    o                         使用偏移内存位置
   
    V                         只使用直接内存位置
   
    i                         使用立即整数值
   
    n                         使用值已知的立即整数值
   
    g                         使用任何可用的寄存器和内存位置
   
    除了这些约束之外, 输出值还包含一个约束修饰符:
   
    输出修饰符                             描述
   
    +                         可以读取和写入操作数
   
    =                         只能写入操作数
   
    %                         如果有必要操作数可以和下一个操作数切换
   
    &                         在内联函数完成之前, 可以删除和重新使用操作数
   
    如:
   
    __asm__("assembly code": "=a"(result):"d"(data1),"c"(data2));
   
    把c变量data1存放在edx寄存器中, 把c变量data2存放到ecx寄存器中, 内联汇编的结果
   
    将存放在eax寄存器中, 然后传送给变量result
   
    在扩展的asm语句块中如果要使用寄存器必须使用两个百分号符号
   
    不一定总要在内联汇编代码中指定输出值, 一些汇编指令假定输入值包含输出值, 如movs指令
   
    其他扩展内联汇编知识:
   
    1, 使用占位符
   
    输入值存放在内联汇编段中声明的特定寄存器中, 并且在汇编指令中专门使用这些寄存器。
   
    虽然这种方式能够很好的处理只有几个输入值的情况, 但对于需要很多输入值的情况, 这
   
    中方式显的有点繁琐。 为了帮助解决这个问题, 扩展asm格式提供了占位符, 可以在内联
   
    汇编代码中使用它引用输入和输出值。
   
    占位符是前面加上百分号的数字, 按照内联汇编中列出的每个输入和输出值在列表中的位置,
   
    每个值被赋予从0开始的地方。 然后就可以在汇编代码中引用占位符来表示值。
返回列表