滴水逆向笔记系列-c语言总结3-13.参数_返回值_局部变量_数组反汇编_多维数组-14.结构体

第十三课 c语言6

1.函数返回值

函数如果有返回值,他在函数内会把结果放在寄存器里面,出了函数后把寄存器里的值传递给变量,根据数据类型编译器自己选择几位寄存器(默认eax寄存器),char类型就选择al,short类型就选择ax,int类型就选择eax
-333228599.jpg

2.函数参数传递

参数传递时到push压栈时还是会使用eax32位去压栈
-333170972.jpg

3.参数与局部变量内存分配

注:这里和数组的内存分配不一样
-332364662.jpg
局部变量分配内存时是都占4个字节不管是charshort或int,但真正使用的时候char还是使用了1个字节
image.png

3.数组的本质

一组地址相邻的变量
-331471017.jpg

数组赋值

:::info
char arr[10] = {'A','B','C','D','E','F'}; //编译器默认在结尾添加0x00
char arr[3] = {'A','B','C'}; //但是如果没有留出'\0'的空间,编译器就不会自动添加
char arr2[6] = {'A','B','C','D','E',0}; //注意区分这里的0不是'0'
char buffer[100] = ""; //定义了一个空字符串,字符串中每个字节默认初始为0x00
char buffer[] = ""; //这个数组长度只有1,且默认初始为0x00
:::
数组赋值应该在最后加一个\0表示结尾,后面自动填充0,不然输出数组可能会多出一些垃圾数据
image.png

4.多维数组

二维数组存储原理

  • 二维数组在汇编中的储存和一维数组没有任何区别

image.png

二维数组语法

  • 给定部分值时

image.png
image.png

  • 多给数值是不允许的

image.png

  • 以下是允许的

image.png

二维数组寻址原理

image.png

三维数组

image.png

作业

-333203675.jpg
1、分别存在两个寄存器
image.png
如果没用__int64就会直接截取
image.png

2、数组内存分配

char类型数组和int类型数组内存分配的字节数是不一样的,char类型数组只分一个字节的内存宽度
image.pngimage.png
image.pngimage.png
image.pngimage.png
image.pngimage.png
image.pngimage.png
image.pngimage.png
image.pngimage.png

-331444047.jpg
3、vs优化过了
image.png
看老师vc6的
-308235875.jpg

4、
-331414260.jpg
image.png

image.png
:::info
练习一:
char arr[5][10] ={
{1,2,3,4,5,6,7,8,9,10}
{11,12,13,14,15,16,17,18,19,20}
....
{41,42,43,44,45,46,47,48,49,50}}
练习二:
arr[1][5],编译器当作1x10+5,取下标15的值
练习三:
for(int i = 0;i<5;i++)
{
for(int y = 0 ; y<10 ; y++)
{printf(arr[i][y]); }
}
练习四:
for(int i = 0 ; i < 10 ; i++)
{
if(arr[1][i]>20)
{arr[1][i]=21;}
}
练习五:
for (int i = 0; i < 3; i++)
{
for (int y = 0; y < 4; y++)
{
x += arr[i][y];
}
cout << x << endl;
}
:::

归并排序

image.png
:::info
void a()
{
int arr[8] = { 3,5,7,9,12,25,34,55 };
int add[6] = { 4,7,9,11,13,16 };
int ret[14] = { 0 };
int i = 0;
int y = 0;
int x = 0;
for (; i < 8; i++)
{
for (; y < 6; y++)
{
if (arr[i] < add[y])
{
ret[x] = arr[i];
x++;
break;
}
else if(add[y]<arr[i])
{
ret[x] = add[y];
x++;
}
else
{
ret[x] = add[y];
x++;
y++;
ret[x] = arr[i];
x++;
i++;
break;
}
}
if (y == 6) {
for (; i < 8; i++)
{
ret[x] = arr[i];
x++;
}
}
}
for (int t = 0; t < 14; t++)
{
cout << ret[t] << " " << endl;
}
}
:::
注:循环变量放在里面和外面的区别
image.png

第十四课 c语言7结构体

结构体1

优势:结构体可以定义多种类型,本质就是把一堆不同类型的东西定义打包在一起
定义时不会分配空间,只有在使用的时候才会分配空间
-307427766.jpg

结构体初始化

image.png
定义了两个结构体,最下面定义了一个类型为Mon的变量gsl,这是一个结构体数组,每个gsl[0]变量都有一些空间可以去定义,比如gsl[0].name[0],或者gsl[0].blood。
错误示范
image.png

结构体和数组区分

  • 内存地址等宽为数组,不等宽可以看作结构体,虽然也有等宽的结构体,但是我们一样可以当作数组看待,有时候逆向也没办法把所有代码都准确逆向出来

image.png

  • 结构体和数组都得看是定义在全局还是局部,来判断是直接分配内存还是在堆栈里
  • 结构体的内存分配和局部变量不一样,局部变量都按本机宽度分配,结构体按类型分配

image.png

结构体大时如何把参数传入函数

相当于栈顶开辟一块空间把参数都复制进去
image.png

结构体2

1.数据对齐

结构体存放顺序不一样,内存空间大小不一样
image.png

对齐规则

image.png

#pragma pack

当定义了字节对齐数,在结构体中由最小那个字节对齐,比如#pragma pack(4),char类型还是以1字节对齐,但是__int64就是以4字节对齐,因为__int64和4相比是4小,所以以4为准。
image.png
image.png
image.png

建议

所以建议结构体从小到大存储

typedef

image.pngimage.png

作业

image.pngimage.pngimage.pngimage.png

posted @ 2024-03-14 14:43  小新07  阅读(23)  评论(0编辑  收藏  举报