编译后生成的代码为:
main:
pushl %ebp
movl %esp, %ebp
#APP
movl $100, %eax
#NO_APP
movl $0, %eax
popl %ebp
ret
很明显这是立即数方式。而下一个例子:
int main(int __argc, char* __argv[])
{
JUST_MOV(__argc);
return 0;
}
经编译后生成的代码为:
main:
pushl %ebp
movl %esp, %ebp
#APP
movl 8(%ebp), %eax
#NO_APP
movl $0, %eax
popl %ebp
ret
这个例子是使用内存方式。
一个带有C/C++表达式的内联汇编,其操作表达式被按照被列出的顺序编号,第一个是0,第2个是1,依次类推,GCC最多允许有10个操作表达式。比如:
__asm__ ("popl %0 nt"
"movl %1, %%esi nt"
"movl %2, %%edi nt"
: "=a"(__out)
: "r" (__in1), "r" (__in2));
此例中,__out所在的Output操作表达式被编号为0,"r"(__in1)被编号为1,"r"(__in2)被编号为2。
再如:
__asm__ ("movl %%eax, %%ebx" : : "a"(__in1), "b"(__in2));
此例中,"a"(__in1)被编号为0,"b"(__in2)被编号为1。
如 果某个Input操作表达式使用数字0到9中的一个数字(假设为1)作为它的操作约束,则等于向GCC声明:“我要使用和编号为1的Output操作表达 式相同的寄存器(如果Output操作表达式1使用的是寄存器),或相同的内存地址(如果Output操作表达式1使用的是内存)”。上面的描述包含两个 限定:数字0到数字9作为操作约束只能用在Input操作表达式中,被指定的操作表达式(比如某个Input操作表达式使用数字1作为约束,那么被指定的 就是编号为1的操作表达式)只能是Output操作表达式。
由于GCC规定最多只能有10个Input/Output操作表达式,所以事 实上数字9作为操作约束永远也用不到,因为Output操作表达式排在Input操作表达式的前面,那么如果有一个Input操作表达式指定了数字9作为 操作约束的话,那么说明Output操作表达式的数量已经至少为10个了,那么再加上这个Input操作表达式,则至少为11个了,以及超出GCC的限 制。
5、Modifier Characters(修饰符)
等号(=)和加号(+)用于对Output操作表达式的修 饰,一个Output操作表达式要么被等号(=)修饰,要么被加号(+)修饰,二者必居其一。使用等号(=)说明此Output操作表达式是Write- Only的,使用加号(+)说明此Output操作表达式是Read-Write的。它们必须被放在约束字符串的第一个字母。比如"a="(foo)是非 法的,而"+g"(foo)则是合法的。
当使用加号(+)的时候,此Output表达式等价于使用等号(=)约束加上一个Input表达式。比如
__asm__ ("movl %0, %%eax; addl %%eax, %0" : "+b"(foo)) 等价于
__asm__ ("movl %1, %%eax; addl %%eax, %0" : "=b"(foo) : "b"(foo))










