网站建设与维护作业,深圳网站建设(龙华信科),网址广告,网站页面分析gcc编译c语言中内嵌汇编--ATT and Intel 汇编语法对照寄存器命名#xff1a;ATT: %eaxIntel: eaxATT 语法源地址在左侧#xff0c;目的地址在右侧与Intel 方式语法相反将eax值传入ebxATT: movl %eax, %ebxIntel: mov ebx, eaxATT 语法在立即数前有…gcc编译c语言中内嵌汇编--ATT and Intel 汇编语法对照寄存器命名ATT: %eaxIntel: eaxATT 语法源地址在左侧目的地址在右侧与Intel 方式语法相反将eax值传入ebxATT: movl %eax, %ebxIntel: mov ebx, eaxATT 语法在立即数前有前缀$.ATT: movl $0x0h, %eaxIntel: mov eax,0x0hATT 语法在操作符后跟表示操作数类型的后缀b,w,l分别表示字节字双字相当于伪操作符ptr如果不加的话GAS会guessATT: movw %ax, %bxIntel: mov bx, ax内存寻址方式ATT: immed32(basepointer,indexpointer,indexscale)Intel: [basepointer indexpointer*indexscale immed32]地址计算公式为immed32 basepointer indexpointer * indexscale直接寻址ATT: _aIntel: [_a]间接寻址ATT: (%eax)Intel: [eax]相对寻址ATT: _variable(%eax)Intel: [eax _variable]ATT: _array(,%eax,4)Intel: [eax*4 array]C 代码: *(p1) p定义为char *ATT: 1(%eax) where eax has the value of pIntel: [eax 1]结构体数组寻址结构体长度为8下标存于eax结构体内偏移地址存于ebx_array为结构体数组首地址ATT: _array(%ebx,%eax,8)Intel: [ebx eax*8 _array]函数内部实现交换1、输入与输出变量相同汇编代码部分标准的交换实现输入部分用0寄存器表示r(a)中所指定的寄存器即输入与输出变量相同int main(){ 804842c: mov 0xfffffff4(%ebp),%ecxint a 10, b 0; 804842f: mov 0xfffffff0(%ebp),%edxprintf(before swap: a %2d, b %2d\n, a , b); 8048432: mov %ecx,%ebx__asm__(nop; 8048434: mov %edx,%esimovl %0, %%eax; 8048436: nopmovl %1, %0; 8048437: mov %ebx,%eaxmovl %%eax, %1; 8048439: mov %esi,%ebxnop; 804843b: mov %eax,%esi: 804843d: nopr(a), r(b) 804843e: mov %ebx,%edx: 8048440: mov %esi,%ecx0(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),%eaxmovl %2, %1; 8048431: nopmovl %3, %0; 8048432: mov %edx,%ebxnop; 8048434: mov %eax,%ecx: 8048436: nopr(a), r(b) 8048437: mov %ecx,%eax: 8048439: mov %ebx,%edxr(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,%eaxreturn 0; 8048442: mov %eax,0xfffffff4(%ebp)}3、交换函数需要间接寻址#includevoid swap(int* x, int* y) 08048400 :{ 8048400: push %ebp__asm__(nop; 8048401: mov %esp,%ebpmovl (%0), %%eax; 8048403: push %ebxmovl (%1), %%ebx; 8048404: mov 0x8(%ebp),%ecxmovl %%ebx, (%0); 8048407: mov 0xc(%ebp),%edxmovl %%eax, (%1); 804840a: nopnop; 804840b: mov (%ecx),%eax: 804840d: mov (%edx),%ebx: 804840f: mov %ebx,(%ecx)r(x),r(y) 8048411: mov %eax,(%edx): 8048413: nopeax, ebx, memory 8048414: mov (%esp,1),%ebx ;ebx还原); 8048417: leave ;movl %ebp, %esp; pop ebp} 8048418: ret8048419: lea 0x0(%esi),%esiint 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 %ebp1: 89 e5 mov %esp,%ebp3: 83 ec 04 sub $0x4,%esp6: 8b 45 0c mov 0xc(%ebp),%eax9: 03 45 08 add 0x8(%ebp),%eaxc: 89 45 fc mov %eax,0xfffffffc(%ebp)f: 8b 45 fc mov 0xfffffffc(%ebp),%eax12: 89 c0 mov %eax,%eax14: c9 leave15: c3 ret16: 89 f6 mov %esi,%esi2 编写内嵌汇编语言函数分析为函数构建运行时堆栈情况即可使其顺利运行由于编译器在函数执行开始和结束时会增加routine beginpush %ebp; mov %esp, %ebproutine 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; retiii 输出部分为:a(r):$ vi sumassemble.cint 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 %ebp1: 89 e5 mov %esp,%ebp3: 83 ec 04 sub $0x4,%esp6: 83 ec 04 sub $0x4,%esp9: 8b 45 0c mov 0xc(%ebp),%eaxc: 03 45 08 add 0x8(%ebp),%eaxf: 89 45 fc mov %eax,0xfffffffc(%ebp)12: 8b 45 fc mov 0xfffffffc(%ebp),%eax15: 89 c0 mov %eax,%eax17: 89 c0 mov %eax,%eax19: 89 45 fc mov %eax,0xfffffffc(%ebp)1c: 8b 45 fc mov 0xfffffffc(%ebp),%eax1f: 89 c0 mov %eax,%eax21: c9 leave22: c3 ret23: 90 nop3 编译可执行程序$ vi summain.cextern 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