欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

gcc 下内联汇编的一些简单案例讲解

程序员文章站 2022-06-17 22:49:06
...

具体的教程 参考转载的前一篇博文 GCC 内联汇编 https://blog.****.net/m0_37329910/article/details/89465064
持续更新中

案列

demo1

直接看代码

char dest_m[0x20] = {'\0'};
static inline char * strcpy_zj(char * dest,const char *src)
{
        int d0, d1, d2;
        __asm__ __volatile__(  "1:\tlodsb\n\t"
                       "stosb\n\t"
                       "testb %%al,%%al\n\t"
                       "jne 1b"
                     : "=&S" (d0), "=&D" (d1), "=&a" (d2)
                     : "0" (src),"1" (dest)
                     : "memory");
        return dest;
}
int main(){
                char *src_m = "zhangji";
                strcpy_zj(dest_m, src_m);
                return 0;
}

编译

gcc -m32 -g demo1.c -o demo1

基本知识点
先解释下内联汇编中的 修饰约束 (第三个冒号后面)
基本格式为:
asm ( 汇编程序模板
: 输出操作数 /* 可选的 /
: 输入操作数 /
可选的 /
: 修饰寄存器列表 /
可选的 */
);

当使用约束时,对于更精确的控制超过了对约束作用的需求,GCC 给我们提供了约束修饰符。最常用的约束修饰符为:

  • “=” : 意味着对于这条指令,操作数为只写的;旧值会被忽略并被输出数据所替换。
  • “&” : 意味着这个操作数为一个早期改动的操作数,其在该指令完成前通过使用输入操作数被修改了。因此,这个操作数不可以位于一个被用作输出操作数或任何内存地址部分的寄存器。如果在旧值被写入之前它仅用作输入而已,一个输入操作数可以为一个早期改动操作数。

直接看汇编代码

Dump of assembler code for function strcpy_zj:
   0x080483ed <+0>:     push   ebp
   0x080483ee <+1>:     mov    ebp,esp
   0x080483f0 <+3>:     push   edi
   0x080483f1 <+4>:     push   esi
   0x080483f2 <+5>:     sub    esp,0x10
   0x080483f5 <+8>:     mov    edx,DWORD PTR [ebp+0xc]   !!!arg2  src
   0x080483f8 <+11>:    mov    eax,DWORD PTR [ebp+0x8]  !!!arg1 dest
   0x080483fb <+14>:    mov    ecx,edx
   0x080483fd <+16>:    mov    edx,eax
   0x080483ff <+18>:    mov    esi,ecx      !!! esi
   0x08048401 <+20>:    mov    edi,edx    !!! edi
   0x08048403 <+22>:    lods   al,BYTE PTR ds:[esi]
   0x08048404 <+23>:    stos   BYTE PTR es:[edi],al
   0x08048405 <+24>:    test   al,al
   0x08048407 <+26>:    jne    0x8048403 <strcpy_zj+22>
   0x08048409 <+28>:    mov    edx,edi   !!! edi
   0x0804840b <+30>:    mov    ecx,esi   !!! esi
   0x0804840d <+32>:    mov    DWORD PTR [ebp-0x14],ecx   !!! &d0 , esi
   0x08048410 <+35>:    mov    DWORD PTR [ebp-0x10],edx   !!!  &d1, edi
   0x08048413 <+38>:    mov    DWORD PTR [ebp-0xc],eax     !!! &d2, eax
   0x08048416 <+41>:    mov    eax,DWORD PTR [ebp+0x8]
=> 0x08048419 <+44>:    add    esp,0x10
   0x0804841c <+47>:    pop    esi
   0x0804841d <+48>:    pop    edi
   0x0804841e <+49>:    pop    ebp
   0x0804841f <+50>:    ret

代码中 d0 d1 d2 与寄存器的关系 进行了跟踪 基本明了

相关标签: gcc 内联汇编