标签:style blog http ar color os 使用 sp 数据
前言
最近开始在看赵老师的书,其中很清晰的讲述了gcc中嵌入式汇编的方法,于是在这里加上自己的理解。
正文
先看赵老师的例子和说明
asm ( “汇编代码语句块”; : 输出寄存器(列表) : 输入寄存器(列表) : 可能(会) 被修改的寄存器(列表) );
这个是gcc 嵌入式汇编的格式,来看一段例程:
1 #define get_seg_byte(seg, addr) 2 ({ 3 register char __res; 4 __asm__("push %%fs;\ 5 mov %%ax, %%fs; 6 mmovb %%fs:%2, %%al; 7 pop %%fs" \ 8 :"=a" (__res) 9 :"0"(seg), "m"(*(addr)));10 __res;})
是的,这个就是赵老师的例子。
按照他的讲解:宏函数 get_seg_byte(seg, addr); 就是去 地址 seg+addr的地方读取一个字节的数据,这个数据最后放到__res变量中,然后返回。
而他对嵌入式汇编的格式的解释,不再重述,网络上也比较多。下面贴上两条资料以供参考:
http://oss.org.cn/kernel-book/ch02/2.6.3.htm
http://blog.csdn.net/littlehedgehog/article/details/2259665
下面来说说我自己的怎么来理解的,或者说如果是我自己,该怎么去这个地址上取值的:
char get_seg_byte(seg, addr) { //将seg 与addr代表的值保存下来 eax = seg; mem = (*(addr)) ; //保存fs段寄存器的值,一般的,c语言中喜欢使用temp这个关键字,但是在这里,直接push即可 push %%fs; //将eax的值赋值给段寄存器fs mov %%ax, %%fs; // fs = ax; //取 seg+addr上的一个值,放入al寄存器 movb %%fs:%2, %%al; // al = *(seg+addr)
//恢复段寄存器fs的值
pop %%fs; //将 eax中的值拷贝给一个C语言的变量 char __res; __res = ax; //其实就是 al 中的值 ,因为 ax = ah +al return __res; }
其实,说简单了,gcc 内嵌汇编并不难。而是自己习惯于C语言这种格式,注意是格式---仅仅是一种格式而已。上面asm 也仅仅是一种人规定的格式而已,并无其他玄妙之处。这样说吧:
gcc内嵌汇编的
:"0"(seg), "m"(*(addr)));
的这一句,其实就等同于我C伪代码的这两句:
//将seg 与addr代表的值保存下来
eax = seg;
mem = (*(addr)) ;
而gcc内嵌汇编的
:"=a" (__res) \
就等同于:
char __res;
__res = ax; //其实就是 al 中的值 ,因为 ax = ah +al
其他部位的意思就是一样的了。
可能是,gcc 内嵌汇编,那种格式,应该是分类更加清晰---按照集合划分:逻辑是一块儿;要使用的寄存器另外给一个list。
写在后面
世界确实是可以理解的,关键是每个人的理解方法。
标签:style blog http ar color os 使用 sp 数据
原文地址:http://www.cnblogs.com/chineseboy/p/4152174.html