linux c语言编程内嵌汇编,gcc编译c语言中内嵌汇编
gcc編譯c語言中內嵌匯編
--AT&T and Intel 匯編語法對照
寄存器命名:
AT&T:? %eax
Intel: eax
AT&T 語法源地址在左側,目的地址在右側與Intel 方式語法相反
將eax值傳入ebx
AT&T:? movl %eax, %ebx
Intel: mov ebx, eax
AT&T 語法在立即數前有前綴$.
AT&T:? movl $0x0h, %eax
Intel: mov eax,0x0h
AT&T 語法在操作符后跟表示操作數類型的后綴b,w,l分別表示字節,字,雙字,相當于偽操作符ptr,如果不加的話GAS會guess
AT&T:? movw %ax, %bx
Intel: mov bx, ax
內存尋址方式
AT&T:? immed32(basepointer,indexpointer,indexscale)
Intel: [basepointer + indexpointer*indexscale + immed32]
地址計算公式為:
immed32 + basepointer + indexpointer * indexscale
直接尋址
AT&T:? _a
Intel: [_a]
間接尋址
AT&T:? (%eax)
Intel: [eax]
相對尋址
AT&T: _variable(%eax)
Intel: [eax + _variable]
AT&T:? _array(,%eax,4)
Intel: [eax*4 + array]
C 代碼: *(p+1) p定義為char *
AT&T:? 1(%eax) where eax has the value of p
Intel: [eax + 1]
結構體數組尋址,結構體長度為8,下標存于eax,結構體內偏移地址存于ebx,_array為結構體數組首地址
AT&T:? _array(%ebx,%eax,8)
Intel: [ebx + eax*8 + _array]
函數內部實現交換
1、輸入與輸出變量相同
匯編代碼部分標準的交換實現,輸入部分用0寄存器表示"=r"(a)中所指定的寄存器即輸入與輸出變量相同
int main()
{??????????????????????????????????????????????????????? ? ?????????????????? 804842c:????? mov??? 0xfffffff4(%ebp),%ecx
int a = 10, b = 0;??????????????????????????????????????????????????? 804842f:????? mov??? 0xfffffff0(%ebp),%edx
printf("before swap: a = %2d, b = %2d\n", a , b);?? 8048432:????? mov??? %ecx,%ebx
__asm__("nop;????????????????????????????????????????????????????? 8048434:????? mov??? %edx,%esi
movl %0, %%eax;??????????????????????????????????????? 8048436:????? nop
movl %1, %0;??????????????????????????????????????????????8048437:????? mov??? %ebx,%eax
movl %%eax, %1;??????????????????????????????????????? 8048439:????? mov??? %esi,%ebx
nop;"??????????????????????????????????????????????????????????? 804843b:????? mov??? %eax,%esi
:????????????????????????????????????????????????????????????????????804843d:????? nop
"=r"(a), "=r"(b)???????????????????????????????????????????? 804843e:????? mov??? %ebx,%edx
:??????????????????????????????????????????????????????????????????? 8048440:????? mov??? %esi,%ecx
"0"(a), "1"(b)??????????????????????????????????????????????? 8048442:????? mov??? %edx,%eax
:??????????????????????????????????????????????????????????????????? 8048444:????? mov??? %eax,0xfffffff4(%ebp)
"%eax"?????????????????????????????????????????????????????????8048447:????? mov??? %ecx,%eax
);?????????????????????????????????????????????????????????????????? 8048449:????? mov??? %eax,0xfffffff0(%ebp)
printf("after? swap: a = %2d, b = %2d\n", a, b);
return 0;
}
2、輸入與輸出用不同的寄存器,&表示輸入輸出需要分配不同的寄存器
int main()
{
int a = 10, b = 0;
printf("before swap: a = %2d, b = %2d\n", a, b);????????? 804842b:????? mov??? 0xfffffff8(%ebp),%edx
__asm__("nop;????????????????????????????????????????????????????????????804842e:????? mov??? 0xfffffff4(%ebp),%eax
movl %2, %1;???????????????????????????????????????????????????? 8048431:????? nop
movl %3, %0;?????????????????????????????????????????????????????8048432:????? mov??? %edx,%ebx
nop;"?????????????????????????????????????????????????????????????????? 8048434:????? mov??? %eax,%ecx
:?????????????????????????????????????????????????????????????????????????? 8048436:????? nop
"=&r"(a), "=&r"(b)????????????????????????????????????????????? 8048437:????? mov??? %ecx,%eax
:????????????????????????????????????????????????????????????????????????? ?8048439:????? mov??? %ebx,%edx
"r"(a), "r"(b)??????????????????????????????????????????????????????? 804843b:????? mov??? %eax,%eax
);???????????????????????????????????????????????????????????????????????? 804843d:????? mov??? %eax,0xfffffff8(%ebp)
printf("after? swap: a = %2d, b = %2d\n", a , b);?? ??????? 8048440:????? mov??? %edx,%eax
return 0;?????????????????????????????????????????????????????????????????????? 8048442:????? mov??? %eax,0xfffffff4(%ebp)
}
3、交換函數,需要間接尋址
#include
void swap(int* x, int* y)?????08048400 :
{????????????????????????????????????????????????????????????????????????????????????????? 8048400:????? push?? %ebp
__asm__("nop;???????????????????????????????????????????????????????????? 8048401:????? mov??? %esp,%ebp
movl (%0), %%eax;??????????????????????????????????????????? 8048403:????? push?? %ebx
movl (%1), %%ebx;??????????????????????????????????????????? 8048404:????? mov??? 0x8(%ebp),%ecx
movl %%ebx, (%0);??????????????????????????????????????????? 8048407:????? mov??? 0xc(%ebp),%edx
movl %%eax, (%1);????????????????????????????????????????????804840a:????? nop
nop;"?????????????????????????????????????????????????????????????????? 804840b:????? mov??? (%ecx),%eax
:?????????????????????????????????????????????????????????????????????????? 804840d:????? mov??? (%edx),%ebx
:???????????????????????????????????????????????????????????????????????????804840f:????? mov??? %ebx,(%ecx)
"r"(x),"r"(y)????????????????????????????????????????????????????????? 8048411:????? mov??? %eax,(%edx)
:?????????????????????????????????????????????????????????????????????????? 8048413:????? nop
"eax", "ebx", "memory"??????????????????????????????????????? 8048414:????? mov??? (%esp,1),%ebx ;ebx還原
);?????????????????????????????????????????????????????????????????????????8048417:????? leave?? ;movl %ebp, %esp; pop ebp
}???????????????????????????????????????????????????????????????????????????????????????? 8048418:????? ret
8048419:????? lea??? 0x0(%esi),%esi
int main()
{
int a = 10, b = 0;
printf("before swap: a = %2d, b = %2d\n", a, b);
swap(&a, &b);
printf("after? swap: a = %2d, b = %2d\n", a, b);
return 0;
}
4、從匯編代碼中分離函數
1> 獲得匯編代碼
這里用加法函數,源代碼為:
int sum(int a, int b)
{
int c = a + b;
return c;
}
對應的匯編代碼為
Disassembly of?????????? section .text:
00000000 :
0:?? 55??????????????????????? push?? %ebp
1:?? 89 e5?????????????????? mov??? %esp,%ebp
3:?? 83 ec 04??????????????sub??? $0x4,%esp
6:?? 8b 45 0c??????????????mov??? 0xc(%ebp),%eax
9:?? 03 45 08??????????????add??? 0x8(%ebp),%eax
c:?? 89 45 fc???????????????mov??? %eax,0xfffffffc(%ebp)
f:?? 8b 45 fc????????????????mov??? 0xfffffffc(%ebp),%eax
12:?? 89 c0??????????????????mov??? %eax,%eax
14:?? c9???????????????????????leave
15:?? c3?????????????????????? ret
16:?? 89 f6?????????????????? mov??? %esi,%esi
2> 編寫內嵌匯編語言函數
分析:為函數構建運行時堆棧情況即可使其順利運行,由于編譯器在函數執行開始和結束時會增加
routine begin:
push %ebp; mov %esp, %ebp
routine end:
leave; ret
將上面的0, 1, 14, 15去掉,返回參數放在eax中將輸出部分設置為"=a"(r) 用eax寄存器 r 為需要的return type
步驟:
i?? 定義return_type r 變量
ii? 去掉push %ebp; mov %esp, %ebp;?? leave; ret
iii 輸出部分為:"=a"(r):
$ vi sumassemble.c
int sum(int a, int b)
{
int r;
__asm__("sub $0x4, %%esp;
movl 0xc(%%ebp), %%eax;
addl 0x8(%%ebp), %%eax;
movl %%eax, 0xfffffffc(%%ebp);
movl 0xfffffffc(%%ebp), %%eax;
movl %%eax, %%eax;"
:
"=a"(r)
);
return r;
}
Disassembly of?????????? section .text:
00000000 :
0:?? 55??????????????????????? push?? %ebp
1:?? 89 e5?????????????????? mov??? %esp,%ebp
3:?? 83 ec 04??????????????sub??? $0x4,%esp
6:?? 83 ec 04??????????????sub??? $0x4,%esp
9:?? 8b 45 0c??????????????mov??? 0xc(%ebp),%eax
c:?? 03 45 08??????????????add??? 0x8(%ebp),%eax
f:?? 89 45 fc??????????????? mov??? %eax,0xfffffffc(%ebp)
12:?? 8b 45 fc??????????????mov??? 0xfffffffc(%ebp),%eax
15:?? 89 c0??????????????????mov??? %eax,%eax
17:?? 89 c0??????????????????mov??? %eax,%eax
19:?? 89 45 fc??????????????mov??? %eax,0xfffffffc(%ebp)
1c:?? 8b 45 fc??????????????mov??? 0xfffffffc(%ebp),%eax
1f:?? 89 c0?????????????????? mov??? %eax,%eax
21:?? c9?????????????????????? leave
22:?? c3?????????????????????? ret
23:?? 90?????????????????????? nop
3> 編譯可執行程序
$ vi summain.c
extern int sum(int ,int);
int main()
{
int x = sum(1,2);
printf("x = %d\n", x);
return 0;
}
$ cc -o sum_main sum_main.c sum_assemble.c
$ ./sum_main
總結
以上是生活随笔為你收集整理的linux c语言编程内嵌汇编,gcc编译c语言中内嵌汇编的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux内核分析与移植,内核分析移植
- 下一篇: linux 连接两个异构网,如何在Lin