鱼C论坛

 找回密码
 立即注册
查看: 2527|回复: 15

[已解决]c语言第22课,小甲鱼老师解释数组名是地址信息

[复制链接]
发表于 2018-6-24 20:51:46 | 显示全部楼层 |阅读模式
10鱼币
我看反汇编觉的数组名和变量一样的,只是个别名

lea eax, [str]

scanf,只是数组前加了一个隐形的‘&‘
最佳答案
2018-6-24 20:51:47
只是一个符号而已

        p = arr;
0007F118 8D 85 50 FE FF FF    lea         eax,[arr]  
0007F11E 89 45 E8             mov         dword ptr [p],eax  


        p = arr;
0007F118 8D 85 50 FE FF FF    lea         eax,[ebp+FFFFFE50h]  
0007F11E 89 45 E8             mov         dword ptr [ebp-18h],eax  

GIF.gif

最佳答案

查看完整内容

只是一个符号而已 p = arr; 0007F118 8D 85 50 FE FF FF lea eax,[arr] 0007F11E 89 45 E8 mov dword ptr ,eax p = arr; 0007F118 8D 85 50 FE FF FF lea eax,[ebp+FFFFFE50h] 0007F11E 89 45 E8 mov dword ptr [ebp-18h],eax
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-6-24 20:51:47 | 显示全部楼层    本楼为最佳答案   
只是一个符号而已

        p = arr;
0007F118 8D 85 50 FE FF FF    lea         eax,[arr]  
0007F11E 89 45 E8             mov         dword ptr [p],eax  


        p = arr;
0007F118 8D 85 50 FE FF FF    lea         eax,[ebp+FFFFFE50h]  
0007F11E 89 45 E8             mov         dword ptr [ebp-18h],eax  

GIF.gif
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-6-24 20:52:29 | 显示全部楼层
本帖最后由 wow7jiao 于 2018-6-24 20:54 编辑

#include <stdio.h>

int main(void)
{
        char str[123];

        printf("请输入域名:");

        scanf("%s", str);

        printf("鱼C工作室的域名是:%s\n", str);



       

        return 0;
}

这是源码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-6-24 20:53:39 | 显示全部楼层
有没有老师肯定我一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-6-24 20:55:48 | 显示全部楼层
反汇编截图上传
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-6-24 21:02:37 | 显示全部楼层
#include <stdio.h>

int main(void)
{
0007F0D0 55                   push        ebp  
0007F0D1 8B EC                mov         ebp,esp  
0007F0D3 81 EC 74 02 00 00    sub         esp,274h  
0007F0D9 53                   push        ebx  
0007F0DA 56                   push        esi  
0007F0DB 57                   push        edi  
0007F0DC 8D BD 8C FD FF FF    lea         edi,[ebp-274h]  
0007F0E2 B9 9D 00 00 00       mov         ecx,9Dh  
0007F0E7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
0007F0EC F3 AB                rep stos    dword ptr es:[edi]  
0007F0EE A1 00 70 13 00       mov         eax,dword ptr [__security_cookie (0137000h)]  
0007F0F3 33 C5                xor         eax,ebp  
0007F0F5 89 45 FC             mov         dword ptr [ebp-4],eax  
        int a = 100;
0007F0F8 C7 45 F4 64 00 00 00 mov         dword ptr [a],64h  
        int *p = &a;
0007F0FF 8D 45 F4             lea         eax,[a]  
0007F102 89 45 E8             mov         dword ptr [p],eax  
        int arr[100];
        arr[0] = 10;
0007F105 B8 04 00 00 00       mov         eax,4  
0007F10A 6B C8 00             imul        ecx,eax,0  
0007F10D C7 84 0D 50 FE FF FF 0A 00 00 00 mov         dword ptr arr[ecx],0Ah  

        p = arr;
0007F118 8D 85 50 FE FF FF    lea         eax,[arr]  
0007F11E 89 45 E8             mov         dword ptr [p],eax  

        return 0;
0007F121 33 C0                xor         eax,eax  
}
0007F123 52                   push        edx  
0007F124 8B CD                mov         ecx,ebp  
0007F126 50                   push        eax  
0007F127 8D 15 48 F1 07 00    lea         edx,ds:[7F148h]  
0007F12D E8 0F C2 FF FF       call        @_RTC_CheckStackVars@8 (07B341h)  
0007F132 58                   pop         eax  
0007F133 5A                   pop         edx  
0007F134 5F                   pop         edi  
0007F135 5E                   pop         esi  
0007F136 5B                   pop         ebx  
0007F137 8B 4D FC             mov         ecx,dword ptr [ebp-4]  
0007F13A 33 CD                xor         ecx,ebp  
0007F13C E8 EB C2 FF FF       call        @__security_check_cookie@4 (07B42Ch)  
0007F141 8B E5                mov         esp,ebp  
0007F143 5D                   pop         ebp  
0007F144 C3                   ret  
#include <stdio.h>

int main(void)
{
0007F0D0 55                   push        ebp  
0007F0D1 8B EC                mov         ebp,esp  
0007F0D3 81 EC 74 02 00 00    sub         esp,274h  
0007F0D9 53                   push        ebx  
0007F0DA 56                   push        esi  
0007F0DB 57                   push        edi  
0007F0DC 8D BD 8C FD FF FF    lea         edi,[ebp+FFFFFD8Ch]  
0007F0E2 B9 9D 00 00 00       mov         ecx,9Dh  
0007F0E7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
0007F0EC F3 AB                rep stos    dword ptr es:[edi]  
0007F0EE A1 00 70 13 00       mov         eax,dword ptr ds:[00137000h]  
0007F0F3 33 C5                xor         eax,ebp  
0007F0F5 89 45 FC             mov         dword ptr [ebp-4],eax  
        int a = 100;
0007F0F8 C7 45 F4 64 00 00 00 mov         dword ptr [ebp-0Ch],64h  
        int *p = &a;
0007F0FF 8D 45 F4             lea         eax,[ebp-0Ch]  
0007F102 89 45 E8             mov         dword ptr [ebp-18h],eax  
        int arr[100];
        arr[0] = 10;
0007F105 B8 04 00 00 00       mov         eax,4  
0007F10A 6B C8 00             imul        ecx,eax,0  
0007F10D C7 84 0D 50 FE FF FF 0A 00 00 00 mov         dword ptr [ebp+ecx+FFFFFE50h],0Ah  

        p = arr;
0007F118 8D 85 50 FE FF FF    lea         eax,[ebp+FFFFFE50h]  
0007F11E 89 45 E8             mov         dword ptr [ebp-18h],eax  

        return 0;
0007F121 33 C0                xor         eax,eax  
}
0007F123 52                   push        edx  
0007F124 8B CD                mov         ecx,ebp  
0007F126 50                   push        eax  
0007F127 8D 15 48 F1 07 00    lea         edx,ds:[0007F148h]  
0007F12D E8 0F C2 FF FF       call        0007B341  
0007F132 58                   pop         eax  
0007F133 5A                   pop         edx  
0007F134 5F                   pop         edi  
0007F135 5E                   pop         esi  
0007F136 5B                   pop         ebx  
0007F137 8B 4D FC             mov         ecx,dword ptr [ebp-4]  
0007F13A 33 CD                xor         ecx,ebp  
0007F13C E8 EB C2 FF FF       call        0007B42C  
0007F141 8B E5                mov         esp,ebp  
0007F143 5D                   pop         ebp  
0007F144 C3                   ret  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-6-24 21:06:14 | 显示全部楼层
对一个普通变量赋值
        int a = 100;
0007F0F8 C7 45 F4 64 00 00 00 mov         dword ptr [ebp-0Ch],64h  

取一个普通变量的地址,然后赋值给一个指针
        int *p = &a;
0007F0FF 8D 45 F4             lea         eax,[ebp-0Ch]  
0007F102 89 45 E8             mov         dword ptr [ebp-18h],eax  


把数组名赋值给指针
        p = arr;
0007F118 8D 85 50 FE FF FF    lea         eax,[ebp+FFFFFE50h]  
0007F11E 89 45 E8             mov         dword ptr [ebp-18h],eax  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-6-24 21:07:13 | 显示全部楼层
对数组中的元素赋值

        arr[0] = 10;
0007F105 B8 04 00 00 00       mov         eax,4  
0007F10A 6B C8 00             imul        ecx,eax,0  
0007F10D C7 84 0D 50 FE FF FF 0A 00 00 00 mov         dword ptr [ebp+ecx+FFFFFE50h],0Ah  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-6-24 21:17:57 | 显示全部楼层
本帖最后由 wow7jiao 于 2018-6-24 21:25 编辑

我说错了,数组名在需要的时候会自己提供地址(指针常量,指向固定地址的指针?)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-6-24 21:36:41 | 显示全部楼层
wow7jiao 发表于 2018-6-24 21:17
我说错了,数组名在需要的时候会自己提供地址(指针常量,指向固定地址的指针?)

什么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-6-24 21:41:01 | 显示全部楼层
本帖最后由 wow7jiao 于 2018-6-24 21:45 编辑


数组名是指向固定的地址的指针,偏正语法指针常量
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-6-24 21:53:31 | 显示全部楼层
wow7jiao 发表于 2018-6-24 21:41
数组名是指向固定的地址的指针,偏正语法指针常量

就只是一个符号而已
你写
int a = 100;
编译器就知道你要访问  dword ptr [ebp-0Ch] 内存单元,并把这个内存单元改写为 64h

你写
int b = 10;
编译器就知道你要访问  dword ptr [ebp-18h] 内存单元,并把这个内存单元改写为 0ah

你写
a = b;
编译器就知道你要访问  dword ptr [ebp-18h] 内存单元和 dword ptr [ebp-0Ch] 内存单元
并把 dword ptr [ebp-18h] 内存单元的值复制到 dword ptr [ebp-0Ch] 内存单元


        p = arr;
00C7F139 8D 85 44 FE FF FF    lea         eax,[ebp+FFFFFE44h]  
00C7F13F 89 45 DC             mov         dword ptr [ebp-24h],eax  

arr 就是一个地址,就是 ebp+FFFFFE44h 内存地址,把这个内存地址保存到 dword ptr [ebp-24h] 内存地址

#include <stdio.h>

int main(void)
{
00C7F0D0 55                   push        ebp  
00C7F0D1 8B EC                mov         ebp,esp  
00C7F0D3 81 EC 80 02 00 00    sub         esp,280h  
00C7F0D9 53                   push        ebx  
00C7F0DA 56                   push        esi  
00C7F0DB 57                   push        edi  
00C7F0DC 8D BD 80 FD FF FF    lea         edi,[ebp+FFFFFD80h]  
00C7F0E2 B9 A0 00 00 00       mov         ecx,0A0h  
00C7F0E7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00C7F0EC F3 AB                rep stos    dword ptr es:[edi]  
00C7F0EE A1 00 70 D3 00       mov         eax,dword ptr ds:[00D37000h]  
00C7F0F3 33 C5                xor         eax,ebp  
00C7F0F5 89 45 FC             mov         dword ptr [ebp-4],eax  
        int a = 100;
00C7F0F8 C7 45 F4 64 00 00 00 mov         dword ptr [ebp-0Ch],64h  
        int b = 10;
00C7F0FF C7 45 E8 0A 00 00 00 mov         dword ptr [ebp-18h],0Ah  
        a = 1;
00C7F106 C7 45 F4 01 00 00 00 mov         dword ptr [ebp-0Ch],1  
        b = 2;
00C7F10D C7 45 E8 02 00 00 00 mov         dword ptr [ebp-18h],2  
        a = b;
00C7F114 8B 45 E8             mov         eax,dword ptr [ebp-18h]  
00C7F117 89 45 F4             mov         dword ptr [ebp-0Ch],eax  
        b = a;
00C7F11A 8B 45 F4             mov         eax,dword ptr [ebp-0Ch]  
00C7F11D 89 45 E8             mov         dword ptr [ebp-18h],eax  

        int *p = &a;
00C7F120 8D 45 F4             lea         eax,[ebp-0Ch]  
00C7F123 89 45 DC             mov         dword ptr [ebp-24h],eax  
        int arr[100];
        arr[0] = 10;
00C7F126 B8 04 00 00 00       mov         eax,4  
00C7F12B 6B C8 00             imul        ecx,eax,0  
00C7F12E C7 84 0D 44 FE FF FF 0A 00 00 00 mov         dword ptr [ebp+ecx+FFFFFE44h],0Ah  

        p = arr;
00C7F139 8D 85 44 FE FF FF    lea         eax,[ebp+FFFFFE44h]  
00C7F13F 89 45 DC             mov         dword ptr [ebp-24h],eax  

        return 0;
00C7F142 33 C0                xor         eax,eax  
}
00C7F144 52                   push        edx  
00C7F145 8B CD                mov         ecx,ebp  
00C7F147 50                   push        eax  
00C7F148 8D 15 68 F1 C7 00    lea         edx,ds:[00C7F168h]  
00C7F14E E8 EE C1 FF FF       call        00C7B341  
00C7F153 58                   pop         eax  
00C7F154 5A                   pop         edx  
00C7F155 5F                   pop         edi  
00C7F156 5E                   pop         esi  
00C7F157 5B                   pop         ebx  
00C7F158 8B 4D FC             mov         ecx,dword ptr [ebp-4]  
00C7F15B 33 CD                xor         ecx,ebp  
00C7F15D E8 CA C2 FF FF       call        00C7B42C  
00C7F162 8B E5                mov         esp,ebp  
00C7F164 5D                   pop         ebp  
00C7F165 C3                   ret  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-6-24 22:52:37 | 显示全部楼层
本帖最后由 wow7jiao 于 2018-6-24 23:07 编辑
人造人 发表于 2018-6-24 21:53
就只是一个符号而已
你写
int a = 100;


int main()
{
        char str[] = "I love FishC.com";
        int count = 0;

        while (*str++ != '\0')
        {
                count++;
        }

        printf("总共有%d个字符\n", count);



       

        return 0;


------------------------------------------
c语言23课,把str当地址++,又提示str不是左值,22课视频的后半部分,b是数组名,*b ,*(b+1),*(b+2)又是正确,我现在把数组名当指针常量正好可以完美的解释^_^指针常量里面放着地址常量



#include <stdio.h>

int main()
{
        char a[] = "FishC";
        int b[5] = {1, 2, 3, 4, 5};
        float c[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
        double d[5] = {1.1, 2.2, 3.3, 4.4, 5.5};

        // int *p = b;

        // printf("*p = %d, *(p+1) = %d, *(p+2) = %d\n", *p, *(p+1), *(p+2));
        printf("*b = %d, *(b+1) = %d, *(b+2) = %d\n", *b, *(b+1), *(b+2));

        /*
        printf("a[0] -> %p, a[1] -> %p, a[2] -> %p\n", &a[0], &a[1], &a[2]);
        printf("b[0] -> %p, b[1] -> %p, b[2] -> %p\n", &b[0], &b[1], &b[2]);
        printf("c[0] -> %p, c[1] -> %p, c[2] -> %p\n", &c[0], &c[1], &c[2]);
        printf("d[0] -> %p, d[1] -> %p, d[2] -> %p\n", &d[0], &d[1], &d[2]);
        */

        return 0;
}

正好把22课这个部分也可以对上
printf("*b = %d, *(b+1) = %d, *(b+2) = %d\n", *b, *(b+1), *(b+2))//*号是对的指针的间接解引用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-6-24 23:34:31 | 显示全部楼层
先从最简单的来
#include <stdio.h>

int main(void)
{
        int a;
        a = 100;
        a = 0;

        return 0;
}
#include <stdio.h>

int main(void)
{
0105F0A0 55                   push        ebp  
0105F0A1 8B EC                mov         ebp,esp  
0105F0A3 81 EC CC 00 00 00    sub         esp,0CCh  
0105F0A9 53                   push        ebx  
0105F0AA 56                   push        esi  
0105F0AB 57                   push        edi  
0105F0AC 8D BD 34 FF FF FF    lea         edi,[ebp+FFFFFF34h]  
0105F0B2 B9 33 00 00 00       mov         ecx,33h  
0105F0B7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
0105F0BC F3 AB                rep stos    dword ptr es:[edi]  
        int a;
        a = 100;
0105F0BE C7 45 F8 64 00 00 00 mov         dword ptr [ebp-8],64h  
        a = 0;
0105F0C5 C7 45 F8 00 00 00 00 mov         dword ptr [ebp-8],0  

        return 0;
0105F0CC 33 C0                xor         eax,eax  
}
0105F0CE 5F                   pop         edi  
0105F0CF 5E                   pop         esi  
0105F0D0 5B                   pop         ebx  
0105F0D1 8B E5                mov         esp,ebp  
0105F0D3 5D                   pop         ebp  
0105F0D4 C3                   ret  

1.png

        a = 100;
0105F0BE C7 45 F8 64 00 00 00 mov         dword ptr [ebp-8],64h  

ebp - 8 的值就是变量 a 的地址

ebp 现在是 0x0053f8c4
0x0053f8c4 - 8 = 0x53f8bc
0x53f8bc 就是变量 a 的地址

mov         dword ptr [ebp-8],64h  
就是把 0x53f8bc 地址的内容改写为 0x64

执行 mov         dword ptr [ebp-8],64h  之前 0x53f8bc 内存地址中保存的值是 0xcccccccc
执行之后 0x53f8bc 内存地址中保存的值是 0x00000064
2.png
3.png
4.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-6-25 10:47:19 | 显示全部楼层

谢谢老师截图解释

我老是在说数组名是指针常量,其实看了《c和指针》说法。

https://blog.csdn.net/daniel_ice/article/details/6857019

首先引用《C和指针》p141中的理论:
在C中, 在几乎所有使用数组的表达式中,数组名的值是个指针常量,也就是数组第一个元素的地址。 它的类型取决于数组元素的类型: 如果它们是int类型,那么数组名的类型就是“指向int的常量指针“。
看到这里我想应该就知道为什么 会有I 和 III式的结果了。

对于II 和 IV 则是特殊情况,在《C和指针》p142中说到,在以下两中场合下,数组名并不是用指针常量来表示,就是当数组名作为sizeof操作符和单目操作符&的操作数时。 sizeof返回整个数组的长度,而不是指向数组的指针的长度。 取一个数组名的地址所产生的是一个指向数组的指针,而不是一个指向某个指针常量的指针。
所以&a后返回的指针便是指向数组的指针,跟a(一个指向a[0]的指针)在指针的类型上是有区别的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-6-25 11:46:38 | 显示全部楼层
好吧,你是对的
数组名就相当于是用 const 修饰了一下

1.png


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-30 00:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表