分类: LINUX
2008-11-02 12:12:39
最近看到了下面这段代码,刚开始有点迷惑,不过之后将其弄明白了,问题的过程如下:
获取段seg中地址addr处的一个字节:get_seg_byte(seg,addr)
#define get_seg_byte(seg,addr){
register unsigned long_res;\
_ asm _(“push %%fs;mov %%ax,%%fs;movl %%fs:%2,%%eax;pop %%fs”:”=a”(_res):”0”(seg),”m”(*(addr)));\
_res;
})
本条语句的具体操作如下:
1、push %%fs;#将fs的内容压人栈中,用来保存fs寄存器的值,以防止出现错误;
2、mov %%ax,%%fs;#把seg的地址放到fs寄存器中
3、movl %%fs:%2,%%eax;#将段内指定的地址放到eax寄存器中,
其中所使用的那段内联汇编不是很清楚,后来参考了《Assembly language》这本书,最终终于将这段代码弄清楚了。具体解决如下:
asm (“assembly code” : “=a”(result) : “d”(data1), “c”(data2));
这句汇编语言的意思是:将变量data1的值放入到寄存器dx组系列寄存器中,将data2的值放到寄存器cx组系列寄存器中,最后得到的输出值是从ax组系列寄存器中得到的,即在我们使用输出值时,变量result的值是从ax组寄存器中得到的。为什么是ax呢?当然,dx或者其他寄存器也可以,在进行汇编的操作中,我们使用的是寄存器来进行操作的,在操作的最后,我们将最终的值放在寄存器ax组寄存器中,这样结果就只能从组寄存器中获取了。
在内联代码中,每一个输入和输出变量通过其各自的罗列顺序而被标识上了相应的数值标识,从0开始计数。我们称呼为占位符。下面是一个例子,足以说明占位符的简单地使用。
For example, the following inline code:
asm (“assembly code”
: “=r”(result)
: “r”(data1), “r”(data2));
will produce the following placeholders:
❑ %0 will represent the register containing the result variable value.
❑ %1 will represent the register containing the data1 variable value.
❑ %2 will represent the register containing the data2 variable value.
请看下面的这段代码:
asm (“imull %1, %0”
: “=r”(data2)
: “r”(data1), “0”(data2));
上面这段代码的具体功能如下:data2同时为输入和输出变量,这在C语言中是很常见的一种使用方法。
这样的作用是data2输入的时候使用占位符为0的变量,输出的时候也是使用占位符为0的寄存器,这样就减少了寄存器的使用数量,即引入的寄存器数量减少了。