分享
 
 
 

gcc编译c语言中内嵌汇编

王朝c/c++·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

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 <stdio.h>

void swap(int* x, int* y) 08048400 <swap>:

{ 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 <sum>:

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 <sum>:

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有