C和汇编---数组

0x01 初始化数组

1、没有初始化数组

#include "stdio.h"
int main(void)
{int data[4];for (int i=0;i<4;i++){printf("%d\t",data[i]);}return 0;
}

不同系统,输出结果可能不一样:
在这里插入图片描述
反汇编:

4:        int data[4];
5:        for (int i=0;i<4;i++)
00401028 C7 45 EC 00 00 00 00 mov         dword ptr [ebp-14h],0
0040102F EB 09                jmp         main+2Ah (0040103a)
00401031 8B 45 EC             mov         eax,dword ptr [ebp-14h]
00401034 83 C0 01             add         eax,1
00401037 89 45 EC             mov         dword ptr [ebp-14h],eax
0040103A 83 7D EC 04          cmp         dword ptr [ebp-14h],4
0040103E 7D 17                jge         main+47h (00401057)
6:        {
7:            printf("%d\t",data[i]);
00401040 8B 4D EC             mov         ecx,dword ptr [ebp-14h]
00401043 8B 54 8D F0          mov         edx,dword ptr [ebp+ecx*4-10h]
00401047 52                   push        edx
00401048 68 1C 20 42 00       push        offset string "%d\t" (0042201c)
0040104D E8 3E 00 00 00       call        printf (00401090)
00401052 83 C4 08             add         esp,8
8:        }
00401055 EB DA                jmp         main+21h (00401031)
9:
10:       return 0;
00401057 33 C0                xor         eax,eax
11:   }

我们可以看到int data[4];没有生成机器码,说明cpu到这里不会干任何事情。从上面的输出结果可以得出,定义一个数组,会给这个数组分配内存空间如果没有初始化,数组的内容是相应分配空间的内容,这里我们称之为垃圾值

  • jge:大于等于转移

2、部分初始化

#include "stdio.h"
int main(void)
{int data[4]={1,2};for (int i=0;i<4;i++){printf("%d\t",data[i]);}return 0;
}

结果:
在这里插入图片描述
反汇编:

4:        int data[4]={1,2};
00401028 C7 45 F0 01 00 00 00 mov         dword ptr [ebp-10h],1
0040102F C7 45 F4 02 00 00 00 mov         dword ptr [ebp-0Ch],2
00401036 33 C0                xor         eax,eax
00401038 89 45 F8             mov         dword ptr [ebp-8],eax
0040103B 89 45 FC             mov         dword ptr [ebp-4],eax
5:        for (int i=0;i<4;i++)
0040103E C7 45 EC 00 00 00 00 mov         dword ptr [ebp-14h],0
00401045 EB 09                jmp         main+40h (00401050)
00401047 8B 4D EC             mov         ecx,dword ptr [ebp-14h]
0040104A 83 C1 01             add         ecx,1
0040104D 89 4D EC             mov         dword ptr [ebp-14h],ecx
00401050 83 7D EC 04          cmp         dword ptr [ebp-14h],4
00401054 7D 17                jge         main+5Dh (0040106d)
6:        {
7:            printf("%d\t",data[i]);
00401056 8B 55 EC             mov         edx,dword ptr [ebp-14h]
00401059 8B 44 95 F0          mov         eax,dword ptr [ebp+edx*4-10h]
0040105D 50                   push        eax
0040105E 68 1C 20 42 00       push        offset string "%d\t" (0042201c)
00401063 E8 28 00 00 00       call        printf (00401090)
00401068 83 C4 08             add         esp,8
8:        }
0040106B EB DA                jmp         main+37h (00401047)
9:
10:       return 0;
0040106D 33 C0                xor         eax,eax
11:   }

从下面这段代码可以看出,部分初始化,编译器会给数组分配连续的空间,将有值的部分赋值到相应的内存,没有初始化的,复制为0,这就是为什么上面的输出结果为什么后面没有赋值的是0

4:        int data[4]={1,2};
00401028 C7 45 F0 01 00 00 00 mov         dword ptr [ebp-10h],1
0040102F C7 45 F4 02 00 00 00 mov         dword ptr [ebp-0Ch],2
00401036 33 C0                xor         eax,eax
00401038 89 45 F8             mov         dword ptr [ebp-8],eax
0040103B 89 45 FC             mov         dword ptr [ebp-4],eax

3、全部初始化数组

#include "stdio.h"
int main(void)
{int data[4]={1,2,3,4};for (int i=0;i<4;i++){printf("%d\t",data[i]);}return 0;
}

在这里插入图片描述

4:        int data[4]={1,2,3,4};
00401028 C7 45 F0 01 00 00 00 mov         dword ptr [ebp-10h],1
0040102F C7 45 F4 02 00 00 00 mov         dword ptr [ebp-0Ch],2
00401036 C7 45 F8 03 00 00 00 mov         dword ptr [ebp-8],3
0040103D C7 45 FC 04 00 00 00 mov         dword ptr [ebp-4],4
5:        for (int i=0;i<4;i++)
00401044 C7 45 EC 00 00 00 00 mov         dword ptr [ebp-14h],0
0040104B EB 09                jmp         main+46h (00401056)
0040104D 8B 45 EC             mov         eax,dword ptr [ebp-14h]
00401050 83 C0 01             add         eax,1
00401053 89 45 EC             mov         dword ptr [ebp-14h],eax
00401056 83 7D EC 04          cmp         dword ptr [ebp-14h],4
0040105A 7D 17                jge         main+63h (00401073)
6:        {
7:            printf("%d\t",data[i]);
0040105C 8B 4D EC             mov         ecx,dword ptr [ebp-14h]
0040105F 8B 54 8D F0          mov         edx,dword ptr [ebp+ecx*4-10h]
00401063 52                   push        edx
00401064 68 1C 20 42 00       push        offset string "%d\t" (0042201c)
00401069 E8 22 00 00 00       call        printf (00401090)
0040106E 83 C4 08             add         esp,8
8:        }
00401071 EB DA                jmp         main+3Dh (0040104d)
9:
10:       return 0;
00401073 33 C0                xor         eax,eax

可以看出如果一开始全部初始化数组,会立即分配连续空间给数组,每个空间赋值为数组相应位置的值
4、总结
不初始化数组,数组元素存储的是垃圾值;部分初始化数组,剩余的被初始化为0;全部初始化,将值赋值到相应内存空间,而且数组的物理地址连续

0x02多维数组是如何分配空间的

多维数组的初始化情况和一维数组一样,那么多维数组是如何分配空间的呢?我们以二维数组为列:

#include "stdio.h"
int main(void)
{int data[2][2]={{1,2},{3,4}};return 0;
}

反汇编:

4:        int data[2][2]={{1,2},{3,4}};
00401028 C7 45 F0 01 00 00 00 mov         dword ptr [ebp-10h],1
0040102F C7 45 F4 02 00 00 00 mov         dword ptr [ebp-0Ch],2
00401036 C7 45 F8 03 00 00 00 mov         dword ptr [ebp-8],3
0040103D C7 45 FC 04 00 00 00 mov         dword ptr [ebp-4],4
5:
6:        return 0;
00401044 33 C0                xor         eax,eax
7:    }

我们可以看出先将1,2存到连续空间。再将3,4存到接下来的空间(数组的内存空间是连续的),所以这就是为什么上课时老师说把二维数组当成一维数组来理解了,data[0]和data[1]分别为一个一维数组,二维数组按照从左到右,从上到下存储,地址连续

  • int data[2][2]:data是一个两个元素的数组,每个元素内含2个int类型元素的数组
  • data的首地址是data[0],data[0]是一个内含2个int类型值的数组,所以data[1]也是这样

0x03 指针和数组

1、一维数组
我们知道数组名是数组的首地址,可为什么呢?接下来我们分析

#include "stdio.h"
int main(void)
{int data[4]={1,3,7,4};int *p;p=data;printf("%d\n",p[0]);printf("%d\n",*p+2);printf("%d\n",*(p+2));return 0;
}

结果:
在这里插入图片描述
反汇编:

4:        int data[4]={1,3,7,4};
0040D738 C7 45 F0 01 00 00 00 mov         dword ptr [ebp-10h],1
0040D73F C7 45 F4 03 00 00 00 mov         dword ptr [ebp-0Ch],3
0040D746 C7 45 F8 07 00 00 00 mov         dword ptr [ebp-8],7
0040D74D C7 45 FC 04 00 00 00 mov         dword ptr [ebp-4],4
5:        int *p;
6:        p=data;
0040D754 8D 45 F0             lea         eax,[ebp-10h]
0040D757 89 45 EC             mov         dword ptr [ebp-14h],eax
7:        printf("%d\n",p[0]);
0040D75A 8B 4D EC             mov         ecx,dword ptr [ebp-14h]
0040D75D 8B 11                mov         edx,dword ptr [ecx]
0040D75F 52                   push        edx
0040D760 68 1C 20 42 00       push        offset string "%d\t" (0042201c)
0040D765 E8 26 39 FF FF       call        printf (00401090)
0040D76A 83 C4 08             add         esp,8
8:        printf("%d\n",*p+2);
0040D76D 8B 45 EC             mov         eax,dword ptr [ebp-14h]
0040D770 8B 08                mov         ecx,dword ptr [eax]
0040D772 83 C1 02             add         ecx,2
0040D775 51                   push        ecx
0040D776 68 1C 20 42 00       push        offset string "%d\t" (0042201c)
0040D77B E8 10 39 FF FF       call        printf (00401090)
0040D780 83 C4 08             add         esp,8
9:        printf("%d\n",*(p+2));
0040D783 8B 55 EC             mov         edx,dword ptr [ebp-14h]
0040D786 8B 42 08             mov         eax,dword ptr [edx+8]
0040D789 50                   push        eax
0040D78A 68 1C 20 42 00       push        offset string "%d\t" (0042201c)
0040D78F E8 FC 38 FF FF       call        printf (00401090)
0040D794 83 C4 08             add         esp,8
10:       return 0;
0040D797 33 C0                xor         eax,eax

从数组初始化我们看不出来data是数组的首地址吗,但可以从p=data看出

6:        p=data;
0040D754 8D 45 F0             lea         eax,[ebp-10h]
0040D757 89 45 EC             mov         dword ptr [ebp-14h],eax

把 [ebp-10h]偏移地址给eax,eax再赋值给dword ptr [ebp-14h]ebp-10h是第一个元素1的地址,所以data是数组首地址,我们将data值赋值给p,此时p和data可以看成等同的,p[0]就是data[0]。

  • 指针加1是增加一个存储单元,比如说*(p+2),p+2就是增加两个存储单元(int是4byte),所以输出*(p+2)是7
  • 输出p+2,此时p是1,加2是3所以会输出3

2、多维数组
以二维数组为例

#include "stdio.h"
int main(void)
{int data[3][3]={{1,2,3},{4,5,6},{7,8,9}};int (* p)[3];			//指向一个含有3个int类型的数组p=data;printf("%d\n",p);printf("%d\n",*p);printf("%d\n",*(p+1));printf("%d\n",**p);printf("%d\n",p[0]);printf("%d\n",*p[0]);return 0;
}

在这里插入图片描述
反汇编:

4:        int data[3][3]={{1,2,3},{4,5,6},{7,8,9}};
0040D738 C7 45 DC 01 00 00 00 mov         dword ptr [ebp-24h],1
0040D73F C7 45 E0 02 00 00 00 mov         dword ptr [ebp-20h],2
0040D746 C7 45 E4 03 00 00 00 mov         dword ptr [ebp-1Ch],3
0040D74D C7 45 E8 04 00 00 00 mov         dword ptr [ebp-18h],4
0040D754 C7 45 EC 05 00 00 00 mov         dword ptr [ebp-14h],5
0040D75B C7 45 F0 06 00 00 00 mov         dword ptr [ebp-10h],6
0040D762 C7 45 F4 07 00 00 00 mov         dword ptr [ebp-0Ch],7
0040D769 C7 45 F8 08 00 00 00 mov         dword ptr [ebp-8],8
0040D770 C7 45 FC 09 00 00 00 mov         dword ptr [ebp-4],9
5:        int (* p)[3];
6:        p=data;
0040D777 8D 45 DC             lea         eax,[ebp-24h]
0040D77A 89 45 D8             mov         dword ptr [ebp-28h],eax
7:        printf("%d\n",p);
0040D77D 8B 4D D8             mov         ecx,dword ptr [ebp-28h]
0040D780 51                   push        ecx
0040D781 68 1C 20 42 00       push        offset string "%d\t" (0042201c)
0040D786 E8 05 39 FF FF       call        printf (00401090)
0040D78B 83 C4 08             add         esp,8
8:        printf("%d\n",*p);
0040D78E 8B 55 D8             mov         edx,dword ptr [ebp-28h]
0040D791 52                   push        edx
0040D792 68 1C 20 42 00       push        offset string "%d\t" (0042201c)
0040D797 E8 F4 38 FF FF       call        printf (00401090)
0040D79C 83 C4 08             add         esp,8
9:        printf("%d\n",*(p+1));
0040D79F 8B 45 D8             mov         eax,dword ptr [ebp-28h]
0040D7A2 83 C0 0C             add         eax,0Ch
0040D7A5 50                   push        eax
0040D7A6 68 1C 20 42 00       push        offset string "%d\t" (0042201c)
0040D7AB E8 E0 38 FF FF       call        printf (00401090)
0040D7B0 83 C4 08             add         esp,8
10:       printf("%d\n",**p);
0040D7B3 8B 4D D8             mov         ecx,dword ptr [ebp-28h]
0040D7B6 8B 11                mov         edx,dword ptr [ecx]
0040D7B8 52                   push        edx
0040D7B9 68 1C 20 42 00       push        offset string "%d\t" (0042201c)
0040D7BE E8 CD 38 FF FF       call        printf (00401090)
0040D7C3 83 C4 08             add         esp,8
11:       printf("%d\n",p[0]);
0040D7C6 8B 45 D8             mov         eax,dword ptr [ebp-28h]
0040D7C9 50                   push        eax
0040D7CA 68 1C 20 42 00       push        offset string "%d\t" (0042201c)
0040D7CF E8 BC 38 FF FF       call        printf (00401090)
0040D7D4 83 C4 08             add         esp,8
12:       printf("%d\n",*p[0]);
0040D7D7 8B 4D D8             mov         ecx,dword ptr [ebp-28h]
0040D7DA 8B 11                mov         edx,dword ptr [ecx]
0040D7DC 52                   push        edx
0040D7DD 68 1C 20 42 00       push        offset string "%d\t" (0042201c)
0040D7E2 E8 A9 38 FF FF       call        printf (00401090)
0040D7E7 83 C4 08             add         esp,8
13:       return 0;
0040D7EA 33 C0                xor         eax,eax
  • p=data;, printf("%d\n",p[0]);,printf("%d\n",**p);的反汇编看出,数组名和数组名[0]是首元素的地址,printf("%d\n",*p);,数组名像是指向数组名[0]的指针,这就是为什么二维数组的元素可以看成一维数组
  • printf("%d\n",*(p+1));从反汇编里看出,加了0ch,就是加12,并不是加4,二维数组的元素是一维数组,一维数组占3个int类型,所以12,所以*(p+1)指向data[1]
  • 函数里使用二维数组:比如说int sum(int data[][3]),第一个[]表明data是一个指针

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/380324.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

清华大学计算机组成与体系结构,清华大学出版社-图书详情-《计算机组成与体系结构(第2版)》...

作为“21世纪大学本科计算机专业系列教材”&#xff0c;遵照本系列教材评审组专家的意见&#xff0c;本书包括了数字电路基础、计算机组成、计算机体系结构3个部分内容。本书读者对象主要是学习计算机课程的大学生&#xff0c;包括计算机系的学生、软件学院的学生和非计算机专业…

txt如何单独单独选择一列_散列| 单独链接以解决冲突

txt如何单独单独选择一列Prerequisite: Hashing data structure 先决条件&#xff1a; 哈希数据结构 单独链接 (Separate chaining) In separate chaining, we maintain a linked chain for every index in the hash table. So whenever there is a Collison the linked list …

[我研究]Behavior Based Software Theft Detection - Hawk

Xinran Wang, Yoon-Chan Jhi, Sencun Zhu, Peng LiuPSU 背景&#xff1a; Behavior Based Software Theft Detection的系统包含四个步骤&#xff1a; 1、Dynamic Analysis - 产生System Call, Call Stack, Dependences 2、Noise Filtering 3、Extract SCDG Birthmarks 4、Compa…

整除个数

描述 1、2、3… …n这n(0< n<1000000000)个数中有多少个数可以被正整数b整除。 输入 输入包含多组数据 每组数据占一行&#xff0c;每行给出两个正整数n、b。 输出 输出每组数据相应的结果。 样例输入 2 1 5 3 10 4 样例输出 2 1 2 思路&#xff1a;一开始…

2020计算机二级题库第14PPT,计算机二级考试MSOffice考精彩试题库ppt操作题附问题详解.doc...

文档介绍&#xff1a;请在【答题】菜单下选择【进入考生文件夹】命令,并按照题目要求完成下面的操作。注意:以下的文件必须保存在考生文件夹下文慧是新东方学校的人力资源培训讲师,负责对新入职的教师进行入职培训,其PowerPoint演示文稿的制作水平广受好评。最近,她应北京节水展…

操作系统 系统开销比率_操作系统中的最高响应比率下一个(HRRN)调度

操作系统 系统开销比率操作系统中的HRRN调度是什么&#xff1f; (What is HRRN Scheduling in Operating System?) HRRN is the abbreviation of Highest Response Ratio Next Scheduling. It is an optimal scheduling algorithm. HRRN是最高响应率下一个调度的缩写 。 这是…

利用堆栈做循环

程序&#xff1a; #include "stdio.h" int main(int argc,char *argv[]) {char *str"%d";printf("hello world");__asm{ log:lea eax,logpush eaxlea ebx,strpush ebxpush eaxcall printfret 8}return 0;}运行&#xff1a;一直死循环运行下去 …

c# 多线程异步demo

一个 c# winform 多线程异步demo&#xff0c;分享下。 因为例子都很简单&#xff0c;所以不多说明&#xff0c;自己下载吧。转载于:https://www.cnblogs.com/chaobao/archive/2011/08/18/CSharpSync.html

(转)项目管理知识体系术语 123

项目管理知识体系术语(一)本词汇集包括和不包括的术语这个词汇集包括的词汇是&#xff1a;对于项目管理是唯一的&#xff0c;或接近于唯一的词汇(例如&#xff1a;范围说明&#xff0c;工作单元&#xff0c;工作分解结构&#xff0c;关键线路法)。对于项目管理是不是唯一的&…

矩形的个数

描述 在一个3*2的矩形中&#xff0c;可以找到6个1*1的矩形&#xff0c;4个2*1的矩形3个1*2的矩形&#xff0c;2个2*2的矩形&#xff0c;2个3*1的矩形和1个3*2的矩形&#xff0c;总共18个矩形。 给出A&#xff0c;B,计算可以从中找到多少个矩形。 输入 本题有多组输入数据&a…

计算机编程要哪方面天赋,编程要哪门子天赋

开局一张图写代码真的需要天赋吗&#xff1f;有句话是这样说的&#xff1a;论大家的努力程度&#xff0c;远不到拼天赋的时候。我认为所谓的天赋&#xff0c;应该是行业内Top10%水平才需要天赋&#xff0c;比如Linux缔造者Linus Torvalds&#xff0c;苹果发明者斯蒂夫沃兹尼亚克…

VBA之EXCEL删除和设置单元格行高等

‘删除Sheet1上的单元格区域A1:D10,并将其余单元格左移以填补被删除单元格的位置 Sheet1.Range(“A1:D10”).Delete Shift:xlShiftToLeft ‘删除指定行 Range(“1:1”).Delete ‘删除指定列 Columns(5).Delete ‘删除当前行 ActiveCell.EntireRow.Delete ‘删除工作表中的重复行…

java void方法_Java对象类的最终void wait(long ms)方法,包含示例

java void方法对象类最终无效等待(长毫秒) (Object Class final void wait(long ms)) This method is available in java.lang.Object.wait(long ms). 此方法在java.lang.Object.wait(long ms)中可用。 This method causes the current thread to wait for a specified amount …

C和汇编----字符串

字符串是以空字符&#xff08;\0&#xff09;结尾的char类型数组。 0x01 定义字符串和初始化 用双引号括起来的内容称为字符串字面量&#xff0c;也叫字符串常量&#xff0c;双引号中的字符串和编译器自动加入\0字符&#xff0c;都作为字符串存储在内存中 #include "st…

出现此版本的sql server不支持用户实例登陆标志 问题的解决方法

场景: 开发工具vs2005 数据库 sql 2005加入了Enterprise Libraty后,新增了一个data access application block,在写ConnectString的时候,出现这个错误提示,解决办法:在连接属性的设置里边,点高级,将User Instance 设置为false,默认的true,所以才导致这个问题的出现.设置好后,重…

计算机编程输入与输出,计算机编程语言的发展与输入输出设备的使用

计算机编程语言的发展与输入输出设备的使用辽宁大学学报自然科学版第32卷 第2期 2005年JOURNALOFLIAONINGUNIVERSITYNaturalSciencesEditionVol.32 No.2 2005计算机编程语言的发展与输入输出设备的使用宋明杰3(辽宁大学信息科学与技术学院,辽宁沈阳110036)摘 要:在编程中涉…

大小写互换

描述 现在给出了一个只包含大小写字母的字符串&#xff0c;不含空格和换行&#xff0c;要求把其中的大写换成小写&#xff0c;小写换成大写&#xff0c;然后输出互换后的字符串。 输入 第一行只有一个整数m&#xff08;m<10),表示测试数据组数。 接下来的m行&#xff0c…

远控免杀专题1---基础篇

0x01 免杀概念 免杀&#xff0c;也就是反病毒与反间谍的对立面&#xff0c;英文为Anti-AntiVirus&#xff08;简写 Virus AV&#xff09;&#xff0c;逐字翻译就是反-反病毒&#xff0c;翻译为反病毒技术。 0x02 杀毒软件检测方法 1、扫描结束 扫描压缩包技术&#xff1a;即…

查询所有存储过程

--查询所有存储过程selectPr_Name as[存储过程], [参数]stuff((select&#xff0c;[Parameter]from( selectPr.Name asPr_Name,parameter.name Type.Name (convert(varchar(32),parameter.max_length))asParameter fromsys.procedures Pr leftjoinsys.parameters…

使用JavaScript中的示例编号MAX_VALUE属性

数字MAX_VALUE属性 (Number MAX_VALUE Property) MAX_VALUE Property is a Number property in JavaScript and it is used to get the maximum value of a number that is possible in JavaScript. MAX_VALUE属性是JavaScript中的Number属性&#xff0c;用于获取JavaScript中可…