赞
踩
助记符:
例如在加法运算的本地代码中加上 add(addition的缩写)、在比较运算的本地代码中加上 cmp(compare 的缩写)等
这些缩写称为助记符
汇编语言:使用助记符的编程语言称为汇编语言
汇编器:把汇编源代码转换成本地代码的程序叫作汇编器
汇编:汇编器转换的过程称之为汇编
语法结构:是操作码 + 操作数 A(也存在只有操作码没有操作数的指令)
备注:在高级编程语言的源代码中,即使指令和数据在编写时是分散的,编译后也会在段定义中集合汇总起来
图:
汇编语言与 C 语言的区别
1、汇编语言的源代码和本地代码是一一对应的
图:
2、C 语言的源代码同本地代码不是一一对应的 ?
备注:会添加相应的段定义,伪代码和引用的文件库
图:接着往下看
mov指令:
指令中最常使用的是对寄存器和内存进行数据存储,mov 指令的两个操作数,分别用来指定数据的存储地和读出源
mov ebp,esp
mov eax,dword ptr [ebp+8]
push、pop指令:
栈是存储临时数据的区域,它的特点是通过 push 指令和 pop 指令进行数据的存储和读出
图:
C 语言源码
int AddNum(int a, int b)
{
return a + b;
}
void MyFunc()
{
int c;
c = AddNum(123, 456);
}
汇编语言代码
_TEXT segment dword public use32 'CODE' _TEXT ends _DATA segment dword public use32 'DATA' _DATA ends _BSS segment dword public use32 'BSS' _BSS ends DGROUP group _BSS,_DATA _TEXT segment dword public use32 'CODE' _AddNum proc near ; ; int AddNum(int a, int b) ; push ebp mov ebp,esp ; ; { ; return a + b; ; mov eax,dword ptr [ebp+8] add eax,dword ptr [ebp+12] ; ; } ; pop ebp ret _AddNum endp _MyFunc proc near ; ; void MyFunc() ; push ebp mov ebp,esp ; ; { ; int c; ; c = AddNum(123, 456); ; push 456 push 123 call _AddNum add esp,8 ; ; } ; pop ebp ret _MyFunc endp _TEXT ends end
步骤图:
备注:栈结构对传入参数进行压入、压出操作,按照编写顺序进行相应值的转换
特点:“函数的参数是通过栈来传递,返回值是通过寄存器来返回的”
理由:函数调用完毕,使用的栈内存也跟着销毁了,所以将返回值存储到了寄存器当中
为什么局部变量只能在定义该变量的函数内进行参阅呢?
这是因为,局部变量是临时保存在寄存器和栈中的。正如本章前半部分讲的那样,函数内部利用的栈,在函数处理完毕后会恢复到初始状态,因此局部变量的值也就被销毁了,而寄存器也可能会被用于其他目的。因此,局部变量只是在函数处理运行期间临时存储在寄存器和栈上
情景:
在进行函数调用时,发现与预期结果不符
原因分析:
假设 MyFunc1 函数在读出counter 的数值 100 后,还未来得及将它的 2 倍值 200 写入 counter 时,正巧 MyFunc2 函数读出了 counter 的数值 100,那么结果就会导致counter 的数值变成了 200
// 定义全局变量
int counter = 100;
// 定义 MyFunc1 函数
void MyFunc1()
{
counter *= 2;
}
// 定义 MyFunc2 函数
void MyFunc2()
{
counter *=2;
}
mov eax,dword ptr[_counter] ; 将 counter 的值读入 eax 寄存器
add eax,eax ; 将 eax 寄存器的值扩大至原来的 2 倍
mov dword ptr[_counter],eax ; 将 eax 寄存器的数值存入 counter 中
图:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。