1、和输出变量列表一样,使用的寄存器代码依然一样的含义。只是少了 '=' 而已。注意如果一个变量使用 'r' 代码时,既做输出,又做输入的话,在写输入变量对应的寄存器时,就写它在输出列表里对应的编号。如上一个例子中 y 既做输出又做输入,那么刚进入汇编指令时,%0的值便为 y 之前的值 4 ,指令结束后 %0 为 7 , 接着又把 %0 输出到了 y 。
破坏寄存器列表1、这一行告诉 GCC 在内联的汇编代码中,哪些寄存器可能会被使用到(显式/隐式)。那么 GCC 就会在进入内联汇编之前将这些寄存器保存起来,最后再恢复。避免影响到其他的代码。
早期的 GCC 要求把输入、输出用到的寄存器写到破坏列表里面。但是现在的编译器能够自动保存、恢复在输出、输入列表里面用到的寄存器。因此上述的例子中由于没有影响到其他非输出、非输入的寄存器,所以可以省略破坏列表。
看个栗子:
#include <stdio.h> char* strcpy(char *dst, const char *src) { __asm__("cld\n" "1:\tlodsb\n\t" "stosb\n\t" "testb %%al, %%al\n\t" "jne 1b" : :"S" (src), "D" (dst) :"ax"); return dst; } int main(int argc, char *argv[]) { char buf[512]; strcpy(buf,"Hello,AT&T!"); printf("%s\n", buf); return 0; } // 代码中隐式的使用到了 ax 寄存器,因此我们特别的指明了 ax 为被破坏的寄存器。 GCC 的一些新特性1、新的 GCC 允许我们为随机分配的寄存器命名,这样极大的方便我们编写内联汇编代码。看个例子:
#include <stdio.h> int main ( int argc , char *argv[] ) { int a = 1; int b = 2; __asm__("addl %[b], %[a]" : [a] "=r"(a) : [b] "r"(b), "[a]"(a)); printf ("a = %d\n" , a); return 0; }2、其实一看代码,你就明白,只需要在指明 "=r" , "r" 的前面加上 [name] 之后,便可以在汇编指令里面直接通过 %[name] 的方式使用相应分配的寄存器了。
我在阅读 GCC 的使用手册时,发现了这个特性十分方便,因此在这里特别提出。当然还有很多新特性,感兴趣的读者可以自行阅读 GNU GCC 的开发者手册,并寻找有用的特性。记得回来分享哦。
好了,这次就到这里吧!