美文网首页
C语言到汇编-指针与数组1

C语言到汇编-指针与数组1

作者: 故事观察日记 | 来源:发表于2020-04-15 16:45 被阅读0次

    指针是一种保存变量地址的变量。下面代码声明了指针变量p ,它的值是x 的地址:

    int x = 1;
    int *p = &x;
    

    一元运算符&可用于取一个对象的地址。一元运算符*是间接寻址或间接引用运算符,当它作用于指针时,将访问指针所指向的对象。
    下面看一个示例代码:

    /*
    1.指针的声明与定义
    */
    
    int z = 3;
    int *q = &z;
    main(){ 
        int x = 1;
        int y = 2; 
        int *ip = &x;
        y = *ip;  /* 现在 y=1 */
        *ip = 0;  /* 现在 x=0 */      
    }
    

    编译后的汇编相关代码如下:

    .globl _z
        .data
    _z:
        .long   3
    .globl _q
    _q:
        .long   _z
        .text
    _main:
        push    ebp
        mov ebp, esp
        sub esp, 24
        mov DWORD PTR [ebp-4], 1
        mov DWORD PTR [ebp-8], 2
        lea eax, [ebp-4]
        mov DWORD PTR [ebp-12], eax
        mov eax, DWORD PTR [ebp-12]
        mov eax, DWORD PTR [eax]
        mov DWORD PTR [ebp-8], eax
        mov eax, DWORD PTR [ebp-12]
        mov DWORD PTR [eax], 0
        leave
        ret
    

    可以看到,外部变量z 被编译成了一个标号_z ,标号后面是它的值。而外部指针变量q 也被编译成一个标号_q ,它的值就是标号_z。也就是说,指针变量与普通变量编译后名字看起来没什么区别,都是一个标号或地址,只不过指针变量中存的是另一个地址。
    lea 指令指的是加载有效地址(load effective address),与mov 指令进行对比:

    lea eax, [ebp-4]
    mov eax, [ebp-4]
    

    第一行的lea 指令是将[ebp-4] 的地址也就是[ebp-4] 本身的值赋给了eax ;
    第二行的mov 指令则是将[ebp-4] 地址的内存单元中存储的值赋给了eax。
    所以以下两行代码即是原代码中的“int *ip = &x;” 语句:

    lea eax, [ebp-4]
    mov DWORD PTR [ebp-12], eax
    

    这两行代码执行后,栈内存中各变量的值参考以下表格3:


    表格3

    接下来执行代码:

        mov eax, DWORD PTR [ebp-12]
        mov eax, DWORD PTR [eax]
        mov DWORD PTR [ebp-8], eax
        mov eax, DWORD PTR [ebp-12]
        mov DWORD PTR [eax], 0
    

    第1行代码执行后,寄存器eax 的值为[ebp-12] 地址中存的值,对照表格3,也就是ebp-4 ;
    所以第2行代码中的[eax] 也就相当于[ebp-4] ,第2行代码执行后eax 的值为[ebp-4] 地址中存的值,即1;
    第3行代码将eax 的值也就是1存入[ebp-8] 中,[ebp-8]之前存的是y 的值2,此行执行完值变为了1;
    这3行代码完成了原代码中“y = * ip; ”语句的功能。
    第4行代码与第1行相同,执行后eax 的值为ebp-4;
    第5行代码中的[eax] 也就相当于[ebp-4],[ebp-4]之前存的是x 的值1,执行之后[ebp-4]的值变为0,所以变量x 的值也变成了0。
    这2行代码完成了原代码中“*ip = 0;”语句的功能。
    经过以上分析,明白了C语言的指针变量编译后汇编语言是如何实现的。因为汇编中也有lea 这种取地址的指令,所以通过汇编代码似乎并没有比直接理解C语言更深刻更本质,只是多加了一层翻译而已。就当是从另一个角度学习指针吧。
    好了,这篇先写到这里,下一篇继续学习指针与数组的内容。

    相关文章

      网友评论

          本文标题:C语言到汇编-指针与数组1

          本文链接:https://www.haomeiwen.com/subject/oimcvhtx.html