- UID
- 872238
|
九,使用函数
################################################################################################
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开始的地方。 然后就可以在汇编代码中引用占位符来表示值。 |
|