其实并不是要说 Intel 和 AT&T PK 的故事,哈哈。因为首先要熟悉 Intel syntax 的汇编指令写法和 AT&T syntax 汇编指令的写法,所以看下表:
+------------------------------+------------------------------------+
| Intel Code | AT&T Code |
+------------------------------+------------------------------------+
| mov eax,1 | movl $1,%eax |
| mov ebx,0ffh | movl $0xff,%ebx |
| int 80h | int $0x80 |
| mov ebx, eax | movl %eax, %ebx |
| mov eax,[ecx] | movl (%ecx),%eax |
| mov eax,[ebx+3] | movl 3(%ebx),%eax |
| mov eax,[ebx+20h] | movl 0x20(%ebx),%eax |
| add eax,[ebx+ecx*2h] | addl (%ebx,%ecx,0x2),%eax |
| lea eax,[ebx+ecx] | leal (%ebx,%ecx),%eax |
| sub eax,[ebx+ecx*4h-20h] | subl -0x20(%ebx,%ecx,0x4),%eax |
+------------------------------+------------------------------------+
看一个用内联汇编写的例子,计算两数的和:
#include <stdio.h>
int main(void) {
int foo = 10, bar = 15;
__asm__ __volatile__ (
"addl %%ebx, %%eax"
:"=a"(foo)
:"a"(foo), "b"(bar)
:"%eax"
);
printf("foo + bar = %d\n", foo);
return 0;
}
该程序作如下解释:
__asm__
用于表示这是一个内联汇编代码段;__volatile
修饰符,则这段内联汇编代码不会被编译器优化掉,但是如果只是做简单的计算,不会产生任何可能的 side effects,则最好不要加这个修饰符,这样可以使编译器帮助我们优化代码;"=a"(foo)"
表示这段内联汇编代码运行结束后,输出结果放在寄存器%eax
中,然后%eax
中的内容再放到foo
C变量中;"a"(foo)
表示这段内联汇编代码开始运行时,foo
C变量输入到%eax
寄存器中,多个输入值可以用上面示例中的方式表达。constraint
的直译,其实你可以理解为边界条件,即输入输出条件。%eax
的值会被篡改的意思。+---+--------------------+
| r | Register(s) |
+---+--------------------+
| a | %eax, %ax, %al |
| b | %ebx, %bx, %bl |
| c | %ecx, %cx, %cl |
| d | %edx, %dx, %dl |
| S | %esi, %si |
| D | %edi, %di |
+---+--------------------+
-
转载请注明来自柳大的CSDN博客:Blog.CSDN.net/Poechant
-