C和汇编----存储类别、链接和内存管理

0x01 存储类别

1、作用域

一个C变量的作用域可以是块作用域、函数作用域、函数原型作用域或文件作用域。
1.1 块作用域
块是用一对花括号括起来的代码区域。比如函数体就是一个块。定义在块中的变量具有块作用域,块作用域变量的可见范围是从定义处到包含该定义的块的末尾

1.2 函数作用域
仅用于goto语句的标签。一个标签首次出现在函数的内层块中,它的作用域也延伸至整个函数

1.3 函数原型作用域
用于函数原型中的形参名,作用范围是从形参定义处到原型声明结束。这意味着,编译器在处理函数原型中的形参时只关心它的类型,而形参名通常无关紧要。

1.4文件作用域
变量的定义在函数外面,具有文件作用域,从它的定义处到该定义所在文件的末尾均可见。

2、链接

C变量有3种链接属性:外部链接、内部链接或无链接。具有块作用域、函数作用域或函数原型作用域的变量都是无链接变量。这意味着这些变量属于定义他们的块、函数或原型私有。具有文件作用域的变量可以是外部链接或内部链接。外部链接变量可以在多文件程序中使用,内部链接变量只能在一个文件中使用。当一个文件作用域变量用static修饰时就是内部链接

3、存储期

C有4种存储期:静态存储期、线程存储期、自动存储期、动态分配存储期

  • 静态存储期:在程序的执行期间一直存在,文件作用域具有静态存储期
  • 线程存储期:用于并发程序设计,程序执行可被分为多个线程。从被声明到线程结束一直存在
  • 自动存储期:块作用域的变量通常都具有自动存储期,当程序进入定义这些变量的块时,为这些变量分配内存,当退出这个块时,释放刚才为变量分配的内存
4、存储类别说明符
  • auto:表名变量是自动存储期,只能用于块作用域的变量声明中。由于在块中声明的变量本身就具有自动存储期,所以使用auto主要是为了明确表达要使用外部变量同名的局部变量的意图。
  • register 说明符也只用于块作用域的变量,它把变量归为寄存器存储类别,请求最快速度访问该变量。同时,还保护了该变量的地址不被获取。
  • static 说明符创建的对象具有静态存储期,载入程序时创建对象,当程序结束时对象消失。如果static 用于文件作用域声明,作用域受限于该文件。如果 static 用于块作用域声明,作用域则受限于该块。
  • extern 说明符表明声明的变量定义在别处。如果包含 extern 的声明具有文件作用域,则引用的变量必须具有外部链接。如果包含 extern 的声明具有块作用域,则引用的变量可能具有外部链接或内部链接,这接取决于该变量的定义式声明。
5、小结

在这里插入图片描述

0x02 存储类别和函数

函数也有存储类别,可以是外部函数(默认)或静态函数。外部函数可以被其他文件的函数访问,但是静态函数只能用于其定义所在的文件。

double gamma(double);   /* 该函数默认为外部函数 */
static double beta(int, int);
extern double delta(double, int);

在同一个程序中,其他文件中的函数可以调用gamma()和delta(),但是不能调用beta(),因为以static存储类别说明符创建的函数属于特定模块私有。这样做避免了名称冲突的问题,由于beta()受限于它所在的文件,所以在其他文件中可以使用与之同名的函数。
通常的做法是:用 extern 关键字声明定义在其他文件中的函数。这样做是为了表明当前文件中使用的函数被定义在别处。除非使用static关键字,否则一般函数声明都默认为extern。

在rand0.c文件里:

static unsigned long int next=1;
unsigned int rand0(void)
{next=next*1103515245+12345;return (unsigned int) (next / 65536 )%32768;
}

在r_drive0.c文件里

#include "stdio.h"extern unsigned int rand0(void);int main(void)
{int count;for(count = 0;count<5;count++)printf("%d\n",rand0());return 0;
}

next是静态内部链接,存储期在程序的执行期间一直存在,作用域是rand0.c文件,其他就不可以访问了。
unsigned int rand0(void)是外部函数,其他文件可以调用,用 extern 关键字声明定义rand0.c文件里

0x03 分配内存 malloc()和free()

  • malloc():接收一个参数,是所需内存的字节数,返回动态分配内存块的首字节地址。如果 malloc()分配内存失败,将返回空指针。malloc会找到合适的空闲内存块,这样的内存是匿名的,malloc()函数可用于返回指向数组的指针、指向结构的指针等,所以通常该函数的返回值会被强制转换为匹配的类型
  • free()函数的参数是之前malloc()返回的地址,该函数释放之前malloc()分配的内存,一些操作系统在程序结束时会自动释放动态分配的内存,但是有些系统不会。为保险起见,请使用free(),不要依赖操作系统来清理。
  • malloc()和free()的原型都在stdlib.h头文件中。
  • 因为char表示1字节,malloc()的返回类型通常被定义为指向char的指针。然而,从ANSI C标准开始,C使用一个新的类型:指向void的指针,把指向 void的指针赋给任意类型的指针完全不用考虑类型匹配的问题
#include "stdlib.h"
#include "stdio.h"int main(void)
{double *ptd;int max=5;int number;int i;ptd=(double *)malloc(max*sizeof(double));for(i=0;i<max;i++){ptd[i]=i;printf("%f\n",ptd[i]);}free(ptd);return 0;}

上面的程序是动态分配数组
在这里插入图片描述
反汇编:

6:        double *ptd;
7:        int max=5;
00401028 C7 45 F8 05 00 00 00 mov         dword ptr [ebp-8],5
8:        int number;
9:        int i;
10:
11:       ptd=(double *)malloc(max*sizeof(double));
0040102F 8B 45 F8             mov         eax,dword ptr [ebp-8]
00401032 C1 E0 03             shl         eax,3
00401035 50                   push        eax
00401036 E8 95 00 00 00       call        malloc (004010d0)
0040103B 83 C4 04             add         esp,4
0040103E 89 45 FC             mov         dword ptr [ebp-4],eax
12:
13:           for(i=0;i<max;i++)
00401041 C7 45 F0 00 00 00 00 mov         dword ptr [ebp-10h],0
00401048 EB 09                jmp         main+43h (00401053)
0040104A 8B 4D F0             mov         ecx,dword ptr [ebp-10h]
0040104D 83 C1 01             add         ecx,1
00401050 89 4D F0             mov         dword ptr [ebp-10h],ecx
00401053 8B 55 F0             mov         edx,dword ptr [ebp-10h]
00401056 3B 55 F8             cmp         edx,dword ptr [ebp-8]
00401059 7D 2A                jge         main+75h (00401085)
14:           {
15:               ptd[i]=i;
0040105B DB 45 F0             fild        dword ptr [ebp-10h]
0040105E 8B 45 F0             mov         eax,dword ptr [ebp-10h]
00401061 8B 4D FC             mov         ecx,dword ptr [ebp-4]
00401064 DD 1C C1             fstp        qword ptr [ecx+eax*8]
16:               printf("%f\n",ptd[i]);
00401067 8B 55 F0             mov         edx,dword ptr [ebp-10h]
0040106A 8B 45 FC             mov         eax,dword ptr [ebp-4]
0040106D 8B 4C D0 04          mov         ecx,dword ptr [eax+edx*8+4]
00401071 51                   push        ecx
00401072 8B 14 D0             mov         edx,dword ptr [eax+edx*8]
00401075 52                   push        edx
00401076 68 1C 60 42 00       push        offset string "%f" (0042601c)
0040107B E8 D0 1F 00 00       call        printf (00403050)
00401080 83 C4 0C             add         esp,0Ch
17:           }
00401083 EB C5                jmp         main+3Ah (0040104a)
18:           free(ptd);
00401085 8B 45 FC             mov         eax,dword ptr [ebp-4]
00401088 50                   push        eax
00401089 E8 C2 0A 00 00       call        free (00401b50)
0040108E 83 C4 04             add         esp,4
19:
20:

ptd=(double )malloc(maxsizeof(double));的反汇编是:

0040102F 8B 45 F8             mov         eax,dword ptr [ebp-8]
00401032 C1 E0 03             shl         eax,3
00401035 50                   push        eax
00401036 E8 95 00 00 00       call        malloc (004010d0)
0040103B 83 C4 04             add         esp,4
0040103E 89 45 FC             mov         dword ptr [ebp-4],eax

先将max的值传给eax,左移eax三位,相当于eax乘以8,就是40,刚好是传给malloc的参数值,然后压栈,调用malloc函数,再把eax存入dword ptr [ebp-4]中。
free(ptd);反汇编:

00401085 8B 45 FC             mov         eax,dword ptr [ebp-4]
00401088 50                   push        eax
00401089 E8 C2 0A 00 00       call        free (00401b50)
0040108E 83 C4 04             add         esp,4

先把dword ptr [ebp-4]的值传给eax,就是40,是malloc分配内存的大小,eax入栈,调用free函数,释放这段内存

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

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

相关文章

倒三角(随即输入)

package wsq; import java.util.*; public class wsqyy {public static void main(String[] args) {Scanner wsqnew Scanner(System.in);int xwsq.nextInt();int i,j,k;for(i0;i<x;i)//第一个for循环控制行数&#xff1b;{for(j0;j<i;j)//第二个for循环控制输出&#xff…

调用向量的第i维分量| 使用Python的线性代数

Prerequisite: Linear Algebra | Defining a Vector 先决条件&#xff1a; 线性代数| 定义向量 Linear algebra is the branch of mathematics concerning linear equations by using vector spaces and through matrices. In other words, a vector is a matrix in n-dimensi…

EYQiPa,梦开始的地方

早在2003年&#xff0c;就有EYQiPa的设想&#xff0c;曾经尝试过去做它&#xff0c;不过总是不了了之。也许是当时技术能力不达标&#xff0c;也许是一直以来的对待事物缺少持之以恒的心态&#xff0c;时光如水&#xff0c;转眼8年过去了&#xff0c;这8年当中&#xff0c;总是…

结合struts和hibernate谈J2EE架构的数据表示

结合struts和hibernate谈J2EE架构的数据表示 在 struts hibernate 这种结构中&#xff0c;是不应该把Hibernate产生的PO直接传递给JSP的&#xff0c;不管他是Iterator&#xff0c;还是List&#xff0c;这是一个设计错误。 我来谈谈在J2EE架构中各层的数据表示方法&#xff1a;…

服务器appcrash的问题怎么修复,ghost win7出现appcrash的问题怎么修复

ghost win7出现appcrash的问题怎么修复一位用户说在win7旗舰版电脑中运行程序会出现appcrash错误的提示&#xff0c;appcrash出错想必很多用户都遇到过&#xff0c;也不知道什么原因引起的&#xff0c;导致程序无法正常运行。那么有什么方法可以解决ghost系统win7运行程序出现a…

远控免杀专题9 --- Avet免杀

0x01 免杀能力一查表 几点说明&#xff1a; 1、上表中标识 √ 说明相应杀毒软件未检测出病毒&#xff0c;也就是代表了Bypass。 2、为了更好的对比效果&#xff0c;大部分测试payload均使用msf的windows/meterperter/reverse_tcp模块生成。 3、由于本机测试时只是安装了360全…

字符串startswith_JavaScript字符串startsWith()方法与示例

字符串startswith字符串startsWith()方法 (String startsWith() Method) startsWith() method is a string method in JavaScript, it is used to check whether a string starts with a specified substring or not. startsWith()方法是JavaScript中的字符串方法&#xff0c;用…

方法:求两个数之和 判断两数是否相等

package wsq; import java.util.Scanner; public class wsq { public static void main(String[] args) { double a,b; Scanner wsqnew Scanner(System.in); awsq.nextDouble(); bwsq.nextDouble(); double cadd(a,b); System.out.println(“两数之和为&#xff1a;”…

WF随笔系列之三 --- Code Activity 专题

系列目录&#xff1a;WF随笔系列之三 Out-of-the-Box Activities 专题目录 Code Activity是WF开发中使用最频繁的Activity之一&#xff0c;它要做工作的很简单&#xff0c;就是把一个或者几个Code Exec 一下&#xff0c;当此行为在执行时&#xff0c;触发一个Handlers:Execute…

是知当代之士、驰骛之曹,书读纵横,则思诸侯之变

看到《职来职往》的智联招聘张勇为应聘者设计的一个问题&#xff0c;很有深度&#xff0c;值得借鉴&#xff1a; 是知当代之士、驰骛之曹&#xff0c;书读纵横&#xff0c;则思诸侯之变&#xff1b; 出自原文&#xff1a; 匠成舆者&#xff0c;忧人不贵&#xff1b; 作箭者&…

A5流密码算法

0x01 A5/1流密码算法的基本用法 作用&#xff1a; 用于蜂窝式移动电话系统语言和数字加密 过程&#xff1a; A5/1算法用于用户的手机到基站之间的通信加密&#xff0c;通信内容到基站后先解密变成明文&#xff0c;然后再进行基站到基站之间&#xff0c;以及基站到用户手机之间…

mcq 队列_MCQ | 密码学中作为IDEA,DES,AES,RSA的块密码

mcq 队列1) In the AES-128 algorithm there are mainly __________ similar rounds and _________ round is different from other round. 1)在AES-128算法中&#xff0c;主要有__________个相似的回合&#xff0c;而_________个回合与其他回合不同。 5 similar rounds havin…

Cookie存取和IE页面缓存的问题

最近老是发现在IE里会有Cookie的问题&#xff0c;如IE下面无法登出&#xff0c;或无法登录&#xff0c;或者登录后信息却无法取到&#xff0c;而Firefox下面一直是通过的&#xff0c;都试过好多次了&#xff0c;今天终于找回的主要的原因&#xff1b;Cookie的问题&#xff1a;首…

数组(一维、二维)

1&#xff0c; 动态初始化&#xff1a; int [] arr new int [5] 如果直接输出arr&#xff1b; System.out.print&#xff08;arr&#xff09;&#xff1b; 结果为&#xff1a; [I13b64eb [&#xff1a;表示一维数组&#xff0c;几个就代表几维数组&#xff1b; I&#xff1a;表…

Extjs TextField扩展

Extjs.form.TextField的默认在输入框后面是不能加入文字。在网上找到此方法以备查用。 /** * 重写textfield,为其多加一个属性sideText,在文本框后面加html * author rms * create 2011-08-17*/Ext.override(Ext.form.TextField, { sideText : , onRender : functi…

远控免杀专题10--TheFatRat免杀

0x01 免杀能力一览表 几点说明&#xff1a; 1、上表中标识 √ 说明相应杀毒软件未检测出病毒&#xff0c;也就是代表了Bypass。 2、为了更好的对比效果&#xff0c;大部分测试payload均使用msf的windows/meterperter/reverse_tcp模块生成。 3、由于本机测试时只是安装了360全…

c++语句switch语句_错误:案例标签不在C中的switch语句内

c语句switch语句The error: case label not within a switch statement occurs in C language with switch case statement, when switch (variable/value) statement is terminated by the semicolon (;). 错误&#xff1a;当switch(变量/值)语句由分号( ; )终止时&#xff0c…

远控免杀专题11-Avoidz免杀

0x01 免杀能力一查表 几点说明&#xff1a; 1、上表中标识 √ 说明相应杀毒软件未检测出病毒&#xff0c;也就是代表了Bypass。 2、为了更好的对比效果&#xff0c;大部分测试payload均使用msf的windows/meterperter/reverse_tcp模块生成。 3、由于本机测试时只是安装了360全…

使用方法实现数组的对调与输出

package asdasqq; import java.util.*; public class asdasdad { public static void main(String[] args) { Scanner wsqnew Scanner(System.in); int qwsq.nextInt();//输入q&#xff0c;表示数组arr的大小&#xff1b; int [] arrnew int [q];//定义一个整型数组arr&a…

CAP与流密码

CAP 中流密码的操作 1 、Cipher 下拉菜单中选中Stream 2&#xff0c;设置LFSR 参数&#xff0c;设置好参数后点击Set Key LFSR Size&#xff1a;表示有几个寄存器 Initial key:寄存器的初始状态&#xff0c;每个寄存器初始值是0或1&#xff0c;放在一起转化成十六进制 Feedbac…