CSDN话题挑战赛第2期
参赛话题:学习笔记

目录

一、函数的内部处理

二、全局变量和局部变量


一、函数的内部处理

上一篇博客用汇编分析了 Sample4.c 整个代码过程,现在分析以下AddNum函数的源代码部分,分析一下参数的接收、返回值等机制:

_AddNum    proc    nearpush      ebp                   ---(1)mov       ebp,esp               ---(2)mov       eax,dword ptr[ebp+8]  ---(3)add       eax,dword ptr[ebp+12] ---(4)pop       ebp                   ---(5)ret                             ---(6)
_AddNum    endp

ebp 寄存器的值在(1)中入栈,在(5)中出栈,这主要是为了把函数中用到的ebp 寄存器的内容,恢复到函数调用前的状态

(2)中把负责管理栈地址的esp 寄存器的值赋值到了ebp 寄存器中。这是因为,在mov 指令中方括号内的参数,是不允许指定 esp寄存器的。因此,这里就采用了不直接通过esp,而是用ebp 寄存器来读写栈内容的方法

(3)使用[ebp+8]指定栈中存储的第1个参数123,并将其读出到 eax 寄存器中。像这样,不使用pop指令,也可以参照栈的内容。而之所以从多个寄存器中选择了eax寄存器,是因为eax是负责运算的累加寄存器

通过(4)的add指令,把当前eax 寄存器的值同第2个参数相加后的结果存储在eax寄存器中。[ebp+12]是用来指定第2个参数456的。在C语言中,函数的返回值必须通过eax 寄存器返回,这也是规定。也就是函数的参数是通过栈来传递,返回值是通过寄存器返回的

(6)中ret指令运行后,函数返回目的地内存地址会 自动出栈,据此,程序流程就会跳转返回到(6)(Call_AddNum)的下一行。这时,AddNum函数入口和出口处栈的状态变化,就如下图所示

AddNum函数内部的栈状态变化:

二、全局变量和局部变量

在函数外部定义的变量称之为全局变量,在函数内部定义的变量称为局部变量,全局变量可以在任意函数中使用,局部变量只能在函数定义局部变量的内部使用。下面,通过汇编语言来看一下全局变量和局部变量的不同之处

下面定义的C语言代码分别定义了局部变量和全局变量,并且给各变量进行了赋值,代码:

// 定义被初始化的全局变量
int a1 = 1;
int a2 = 2;
int a3 = 3;
int a4 = 4;
int a5 = 5;//定义没有初始化的全局变量
int b1,b2,b3,b4,b5;//定义函数
void MyFunc(){
//定义局部变量
int c1,c2,c3,c4,c5,c6,c7,c8,c9,c10;//给局部变量赋值
c1 = 1;
c2 = 2;
c3 = 3;
c4 = 4;
c5 = 5;
c6 = 6;
c7 = 7;
c8 = 8;
c9 = 9;
c10 = 10;//把局部变量赋值给全局变量
a1 = c1;
a2 = c2;
a3 = c3;
a4 = c4;
a5 = c5;
b1 = c6;
b2 = c7;
b3 = c8;
b4 = c9;
b5 = c10;
}

用Borland C++ 编译后的汇编代码可以大致分为:

1、初始化的全局变量,会汇总到名为 _DATA 的段定义中

_DATA segment dword public use32 'DATA'
...
_DATA ends

2、没有初始化的全局变量,会汇总到名为 _BSS 的段定义中

_BSS segment dword public use32 'BSS'
...
_BSS ends

3、被段定义 _TEXT 围起来的汇编代码则是 Borland C++定义

_TEXT segment dword public use32 'CODE'
_MyFunc proc near
...
_MyFunc endp
_TEXT ends

汇编指令:

操作码 操作数 功能
add A,B

把A和B的值相加,并把结果赋值为A

call A 调用函数A
cmp A,B 对A和B进行比较,比较结果会自动存入标志寄存器中
inc A 对A的值 +1
ige 标签名 和cmp命令组合使用,跳转到标签行
jl 标签名 和cmp命令组合使用,跳转到标签行
jle 标签名 和cmp命令组合使用,跳转到标签行
jmp 标签名 和cmp命令组合使用,跳转到标签行
mov A,B 把B的值赋给A
pop A 从栈中读取数值并存入A
push A 把A的值存入栈中
ret 将处理返回到调用源
xor A,B A和B进行异或比较,并将结果存入A中

我们首先来看一下_DATA 段定义的内容。_a1 label dword 定义了_a1 这个标签。标签表示的是相对于段定义起始位置的位置。由于_a1_DATA 段定义的开头位置,所以相对位置是0。_a1 就相当于是全局变量a1。编译后的函数名和变量名前面会加一个(_),这也是Borland C++的规定。dd 1 指的是,申请分配了4字节的内存空间,存储着1这个初始值。dd指的是 define double word 表示有两个长度为2的字节领域(word),也就是4字节的意思

Borland C++中,由于 int 类型的长度是4字节,因此汇编器就把int a1=1变换成了_a1 labeldword 和dd 1。同样,这里也定义了相当于全局变量的a2-a5的标签_a2-_a5,它们各自的初始值2-5也被存储在各自的4字节中

接下来,我们来说一说_BSS段定义的内容。这里定义了相当于全局变量b1-b5的标签_b1-_b5。其中的 db 4dup(?)表示的是申请分配了4字节的领域,但值尚未确定(这里用?来表示)的意思。 db(define byte)表示有1个长度是1字节的内存空间。因而,db 4 dup(?)的情况下,就是4字节的内存空间

注意:db 4 dup(?)不要和dd 4混淆了,前者表示的是4个长度是1字节的内存空间。而db4表示的则是双字节(=4字节)的内存空间中存储的值是4

函数的内部处理及全局变量和局部变量相关推荐

  1. 前端:JS/22/函数(函数的概念,函数的定义格式,函数定义格式的说明,函数的调用,函数的参数),全局变量和局部变量,拷贝传值和引用传址,匿名函数,二维数组,对象,自定义对象的创建

    函数 1,函数的概念 函数,是将一段公共的代码进行封装,给它起个名字叫"函数" 函数可以一次定义,多次调用:函数可以将常用的功能代码,进行封装,如:用户名的验证,验证码函数,邮箱验 ...

  2. python函数作用域包括局部变量和参数_python函数变量的作用域声明(全局变量和局部变量)...

    函数变量的作用域声明(全局变量和局部变量) 引入问题: 局部变量: 局部变量:定义在函数内部的变量,它的作用域也仅限于函数内部,出了函数就不能使用了. 例如: #encoding = utf-8 de ...

  3. 搞懂JavaScript全局变量与局部变量,看这篇文章就够了

    目录 1.什么是全局变量和局部变量 2.全局变量和局部变量的声明 2.1 全局变量的声明 2.2 局部变量的声明 3.全局变量和局部变量一些常见问题 3.1全局变量跟局部变量重名 3.2 零散变量的问 ...

  4. python成员变量和全局变量_python 全局变量和局部变量详解笔记

    python,数据分析,有相关问题欢迎留言交流. 一.问题引入 在写爬虫进行批量命名时,比如说常用的解析网页时 url这个变量就是跨函数的.涉及到全局变量和局部变量的设置. 二.全局变量与局部变量的区 ...

  5. python 函数递归一次增加一次变量_python3--函数(函数,全局变量和局部变量,递归函数)...

    1.1函数 1.1.1什么是函数 函数就是程序实现模块化的基本单元,一般实现某一功能的集合. 函数名:就相当于是程序代码集合的名称 参数:就是函数运算时需要参与运算的值被称作为参数 函数体:程序的某个 ...

  6. python函数用法详解2(变量的作用域(全局变量、局部变量)、共享全局变量、函数返回值、函数的参数(位置参数、关键字参数、默认参数、不定长参数)、拆包、交换变量值、引用、可变和不可变类型)

    1. 变量作⽤域         变量作⽤域指的是变量⽣效的范围,主要分为两类:局部变量和全局变量. 局部变量         定义在函数体内部的变量,即只在函数体内部⽣效. def testA(): ...

  7. python函数的 全局变量与局部变量

    一.函数的全局变量 1.什么是全局变量 顶着头开始写,没有任何缩进,在py文件的任何位置都能调用 #!/usr/bin/env python # _*_ coding:utf8 _*_ name=&q ...

  8. 全局变量_Python函数中的全局变量与局部变量

    # a,b变量是全局变量,在整个py文件中都可以访问 a = 11 b = 12 # 定义一个函数 def first(): # 这个变量是函数内部定义的变量,属于局部变量,只能在函数中使用 c = ...

  9. 对于局部变量_浅谈Shell函数中全局变量和局部变量

    Shell中函数的两种变量 这里的两种变量是针对于函数来讲的,非脚本. (1) 全局变量 在函数内部定义的变量 特点: 脚本中主代码可以获取. 注意!!!: 脚本中(函数外部)定义的变量,在本脚本的函 ...

最新文章

  1. 病毒导致win2003服务器共享丢失业务中断
  2. SQL优化避免索引失效
  3. ACM题目————次小生成树
  4. 同一个网站下不同应用程序可以不同Framework版本
  5. mysql 禁止插入重复数据_防止MySQL重复插入数据的三种方法
  6. 计算机科学速成课18:操作系统
  7. 手机浏览器网址_用电脑键盘给手机“隔空打字”的新招!帮你省了蓝牙键盘的钱啦...
  8. ROS语音交互系统_(2)利用讯飞TTS实现ROS下语音合成播报
  9. c语言中printf输出,C语言中printf输出的总结
  10. 顺丰该不该开除删库的运维工程师?
  11. Linux 下的IP/子网计算器:ipcalc
  12. 淘宝直通车展现位置和人群精准如何运用
  13. 批量图像自动分割 grabcut+阈值分割 opencv
  14. 向无所不能逼近的算法 逻辑与算法之一
  15. linux内核中断实践5:threaded_irq
  16. 用VBA在word创建宏,功能是金额数字转换大写
  17. 乔布斯的创新之道:换一种思考方式
  18. nmap学习之路--测试版
  19. 静态网站生成器Gridsome
  20. 外汇交易经济指标解读

热门文章

  1. js ajax获得对象怎么放到td上,jquery通过AJAX从后台获取信息并显示在表格上,并支持行选中...
  2. 【插值】牛顿插值、拉格朗日插值、三次样条插值的Python代码实现
  3. Diffie-Hellman 密钥交换技术(内含多方密钥交换)
  4. 数据丢失怎么办?用数据恢复软件恢复丢失的数据只需2步
  5. IDEA(一):自动导包,删包。
  6. 有理数计算器(程序类图、流程图)
  7. Java-JVM诊断工具Arthas
  8. 如何全面展现运维生态状况
  9. 报告!这群阿里工程师在偷偷养猪
  10. 小白如何从零开始做电商运营