C语言嵌入汇编格式
asm ( "汇编语句"
: 输出寄存器
: 输入寄存器
: 会被修改的寄存器 );
除第一行汇编语句外,后面带冒号的行若不使用就可以省略。
“asm”: 是内嵌汇编语句关键词。
“汇编语句”是写汇编指令的地方;
“输出寄存器”表示这段嵌入汇编执行后,哪些寄存器用于存放输出数据,这些寄存器会分别对应C语言表达式值或一个内存地址
“输入寄存器”表示在开始执行汇编代码时,这里指定的寄存器中存放输入值,它们也分别对应着C语音变量或常数值。
“会被修改的寄存器”表示你已对其中列出的寄存器中的值进行了改动,gcc编译器不能在依赖于它原先对这些寄存器加载得值
列:
#define get_seg_byte(seg, addr) ({ \
register char __res; \ //定义一个寄存器变量 __res
__asm__("push %%fs; \ //首先保存fs寄存器原值 (段选择符)
mov %%ax, %%fs; \ //然后seg设置fs
movb %%fs:%2, %%al;\ // 取seg:addr处1字节内容到al寄存器
pop %%fs" \ //恢复fs寄存器原内容
: "=a" (__res) // 输出寄存器列表
: "0" (seg), "m"(*(addr)));\ //输入寄存器列表
__res; })
嵌入汇编规定把输出和输入寄存器统一按顺序编号,顺序是从输出寄存器序列从左到右从上到下以“%0”开始,分别记为“%0,%1 ..... %9"。
常用寄存器加载代码说明
代码 | 说明 | 代码 | 说明 |
---|---|---|---|
a | 使用寄存器eax | m | 使用内存地址 |
b | 使用寄存器ebx | o | 使用内存地址并可以加偏移值 |
c | 使用寄存器ecx | I | 使用常数0 ~ 31 |
d | 使用寄存器edx | J | 使用常数0 ~ 63 |
S | 使用寄存器esi | K | 使用常数0 ~ 255 |
D | 使用寄存器edi | L | 使用常数0 ~ 65535 |
q | 使用动态分配字节可寻址寄存器(eax,ebx,ecx或edx) | M | 使用常数0 ~ 3 |
r | 使用任意动态分配的寄存器 | N | 使用1字节常数(0 ~ 255) |
g | 使用通用有效的地址即可(eax,ebx,ecx,edx或内存变量) | O | 使用常数0 ~ 31 |
A | 使用eax与edx联合64位 | = | 输出操作数,输出值将替换前值 |
+ | 表示操作数可读可写 | & | 早期会变的操作数,表示在使用完操作数之前,内容会被修改 |