基本格式如下:
asm("汇编语句"
: 输出寄存器
: 输入寄存器
: 会被修改的寄存器
)
汇编语句
是写汇编指令的地方,输出寄存器
表示当这段嵌入汇编语句之后,哪些寄存器用于存放输出数据.这些寄存器会分别对应一个C语言表达式或一个内存地址,输入寄存器
表示在开始执行汇编代码时,这里指定的一些寄存器中应存放的输入值,它们分别对应着一个C变量或常数值.下面用例子来说明嵌入汇编语句的使用方法.
#define get_seg_byte(seg, addr) \
({ \
register char__res; \
__asm__("push %%fs; \
mov %%ax, %%fs; \
movb %%fs: %2, %%al; \
pop %%fs" \
:"=a"(__res) \
:""(seg),"m"(*(addr))); \
__res;})
这段代码定义了一个嵌入汇编语言宏函数.通常使用汇编语句最方便的方式是把它们放在宏内.用圆括号括住的组合语句可以作为表达式使用,其中最后的变量__res
是该表达式的输出值.
因为是宏语句,需要在一行上定义,因此这里使用反斜杠将这些语句连成一行.这条宏定义将被替换到宏名称在程序中被引用的地方.第一行定义了宏的名称,也就是宏函数名称get_seg_byte(seg, addr)
.第三行定义了一个寄存器变量__res
,第四行的__asm__
表示嵌入式汇编语句的开始,第四行到第七行是AT&T格式的汇编语句.
第八行是输出寄存器,这句的含义是在这段代码运行结束后将eax
寄存器的值放入__res
变量中,作为本函数的输出值."=a"
中"a"
称为加载代码,"="
表示这是输出寄存器,第9行表示在这段代码开始运行时将seg放到eax寄存器中,""
表示使用与上面同个位置的输出相同的寄存器.而(*(addr))
表示一个内存偏移地址值.为了在上面汇编语句中使用该地址值,嵌入式汇编程序规定把输出和输入寄存器统一按顺序编号,顺序是从输出寄存器序列从左到右从上到下以"%0"
开始,分别计为%0,%1…%9.因此上面汇编代码中%2
即代表(*(addr))
.
常用寄存器加载代码说明
代码 | 说明 | 代码 | 说明 |
---|---|---|---|
a | eax | m | 使用内存地址 |
b | ebx | o | 使用内存地址并可以增加偏移量 |
c | ecx | ||
d | edx | ||
S | esi | ||
D | edi | ||
r | 使用任意动态分配的寄存器 |
来源:CSDN
作者:、moddemod
链接:https://blog.csdn.net/weixin_43833642/article/details/103849051