Win32汇编学习(1):基本概念
背景知识
Windows 把每一个 Win32 应用程序放到分开的虚拟地址空间中去运行,也就是说每一个应用程序都拥有其相互独立的 4GB 地址空间,当然这倒不是说它们都拥有 4GB 的物理地址空间,而只是说能够在 4GB 的范围内寻址。操作系统将会在应用程序运行时完成 4GB 的虚拟地址和物理内存地址间的转换。这就要求编写应用程序时必须格守 Windows 的规范,否则极易引起内存的保护模式错误。而过去的 Win16 内存模式下,所有的应用程序都运行于同一个 4GB 地址空间,它们可以彼此"看"到别的程序的内容,这极易导致一个应用程序破坏另一个应用程序甚至是操作系统的数据或代码。
和 16 位 Windows 下的把代码分成 DATA,CODE 等段的内存模式不同,WIN32 只有一种内存模式,即 FLAT 模式,意思是"平坦"的内存模式,再没有 64K 的段大小限制,所有的 WIN32 的应用程序运行在一个连续、平坦、巨大的 4GB 的空间中。这同时也意味着您无须和段寄存器打交道,您可以用任意的段寄存器寻址任意的地址空间,这对于程序员来说是非常方便的,这也使得用32位汇编语言和用C语言一样方便。 在Win32下编程,有许多重要的规则需要遵守。有一条很重要的是:Windows 在内部频繁使用 ESI,EDI,EBP,EBX 寄存器,而且并不去检测这些寄存器的值是否被更改,这样当您要使用这些寄存器时必须先保存它们的值,待用完后再恢复它们,一个最显著的应用例子就是 Windows 的 CallBack 函数中。
内容
一般的Win32汇编都有下面的程序段,这是一个Win32汇编编程的基础框架,若您现在还不知道这些指令的确切意义的话,没关系, 随后我就会给大家详细解释。
.386
.MODEL Flat, STDCALL
.DATA
<Your initialized data>
......
.DATA?
<Your uninitialized data>
......
.CONST
<Your constants>
......
.CODE
<label>
<Your code>
.....
end <label>
这就是一般Win32汇编编程的基础框架,其中各个关键词的解释说明如下:
.386
这是一个汇编语言伪指令,他告诉编译器我们的程序是使用80386指令集编写的。您还可以使用 .486、.586, 但最安全的还是使用.386。对于每一种CPU有两套几乎功能相同伪指令: .386/.386P、 486/.486P、 586/.586P。 带P的指令标明您的程序中可以用特权级指令。特权级指令是保留给操作系统的,如虚拟设备驱动程序。在大多数时间,您的程序都无须运行在RING0层,故用不带后缀P的伪指令已足够了。
.MODEL FLAT,STDCALL
.MODEL 是用来指定内存模式的伪指令,在Win32下,只有一种内存模型,那就是FLAT。 STDCALL 告诉编译器参数的传递约定。参数的传递约定是指参数传达时的顺序(从左到右或从右到左)和由谁恢复堆栈指针(调用者或被调用者)。在Win16下有两种约定:C 和 PASCAL。C 约定规定参数传递顺序是从右到左,即最右边的参数最先压栈,由调用者恢复堆栈指针。
例如:为调用函数 foo ( int first_param, int second_param, int third_param ); 按C约定的汇编代码应该是这样的:
push [third_param]
push [second_param]
push [first_param]
call foo
add esp, 3 * 4 ;调用者自己恢复堆栈指针
PASCAL约定和C约定正好相反,它规定参数是从左向右传递,由被调用者恢复堆栈。Win16采用了PASCAL约定, 因为PASCAL约定产生的代码量要小。当不知道参数的个数时,C约定特别有用。如在函数wsprintf () 中, wsprintf预先并不知道要传递几个参数,所以它不知道如何恢复堆栈。STDCALL是C约定和PASCAL约定的混合体,它规定参数的传递是从右到左,恢复堆栈的工作交由被调用者。Win32只用STDCALL约定,但除了一个特例,即:wsprintf。
.DATA
.DATA?
.CONST
.CODE
上面的四个伪指令是"分段"(SECTION)伪指令。我们上面刚讲过Win32下没有"段"(SEGMENT)的概念,但是您可以把您的程序分成不同的"分段", 一个"分段"的开始即是上一个"分段"的结束。WIN32中只有两种性质的"分段":DATA和CODE。
其中DATA"分段"又分为三种:
.DATA其中包括已初始化的数据。.DATA?其中包括未初始化的数据。比如有时您仅想预先分配一些内存但并不想指定初始值。使用未初始化的数据的优点是它不占据可执行文件的大小,如:若您要在.DATA?段中分配10,000字节的空间,您的可执行文件的大小无须增加10,000字节,而仅仅是要告诉编译器在装载可执行文件时分配所需字节。.CONST其中包括常量定义。这些常量在程序运行过程中是不能更改的。 应用程序并不需要以上所有的三个"分段", 可以根据需要进行定义。.CODE这是代码"分段"。
实际上,分段并不是象在 Dos 下一样,为不同的段分别指出不同的段寄存器,因为 Windows 下只有一个 4GB 的段,Windows 程序中的分段表现在当程序装载时,赋予不同的分段不同的属性,比如说当你的程序加载时,对于 Ring3 程序来说,.code 段是不可写的,而 .data 段是可写的,如果你尝试象在 Dos 下一样写自己的代码部分,你会得到一个蓝屏错误
<label>
end <label>
是用来唯一标识您的代码范围的标签, 两个标签必须相同,应用程序的所有可执行代码必须在两个标签之间。
Win32汇编学习(1):基本概念的更多相关文章
- Win32汇编学习(4):绘制文本
这次,我们将学习如何在窗口的客户区"绘制"字符串.我们还将学习关于"设备环境"的概念. 理论: "绘制"字符串 Windows 中的文本是一 ...
- Win32汇编学习(5):绘制文本2
这次我们将学习有关文本的诸多属性如字体和颜色等. 理论: Windows 的颜色系统是用RGB值来表示的,R 代表红色,G 代表绿色,B 代表蓝色.如果您想指定一种颜色就必须给该颜色赋相关的 RGB ...
- Win32汇编学习(3):简单的窗口
这次我们将写一个 Windows 程序,它会在桌面显示一个标准的窗口,以此根据代码来学习如何创建一个简单的窗口. 理论: Windows 程序中,在写图形用户界面时需要调用大量的标准 Windows ...
- Win32汇编学习(10):对话框(1)
现在我们开始学习一些有关GUI编程的有趣的部分:以对话框为主要界面的应用程序. 理论: 如果您仔细关注过前一个程序就会发现:您无法按TAB键从一个子窗口控件跳到另一个子窗口控件,要想转移的话只有 用鼠 ...
- Win32汇编学习(11):对话框(2)
我们将进一步学习对话框,探讨如何把对话框当成输入设备.如果您看了前一篇文章,那就会发现这次的例子只有少量的改动,就是把我们的对话框窗口附属到主窗口上.另外,我们还要学习通用对话框的用法. 理论: 把对 ...
- win32 汇编学习(2):消息框
这一次,我们将用汇编语言写一个 Windows 程序,程序运行时将弹出一个消息框并显示"你好,我的第一个Win32汇编程序". 理论知识 Windows 为编写应用程序提供了大量的 ...
- Win32汇编学习(9):窗口控件
这次我们将探讨控件,这些控件是我们程序主要的输入输出设备. 理论: WINDOWS 提供了几个预定义的窗口类以方便我们的使用.大多数时间内,我们把它们用在对话框中,所以我们一般就它们叫做子窗口控件.子 ...
- Win32汇编学习(7):鼠标输入消息
这次我们将学习如何在我们的窗口过程函数中处理鼠标按键消息.例子演示了如何等待鼠标左键按下消息,我们将在按下的位置显示一个字符串. 理论: 和处理键盘输入一样,WINDOWS将捕捉鼠标动作并把它们发送到 ...
- Win32汇编学习(6):键盘输入消息
这次,我们将要学习WINDOWS程序是如何处理键盘消息的. 理论: 因为大多数的PC只有一个键盘,所以所有运行中的WINDOWS程序必须共用它.WINDOWS 将负责把击键消息送到具有输入焦点的那个应 ...
随机推荐
- [3]传奇3服务器源码分析一 DBServer
留存 服务端下载地址: 点击这里
- cmd下 mysql操作命令大全详解
启动:net start mySql; 进入:mysql -u root -p/mysql -h localhost -u root -p databaseName; 列出数据库:show datab ...
- python pynssql创建表,删除表,插入数据,查询
import pymssql server='10.194.**.***:*****' user='sa' password='******' database='******' #连接 conn=p ...
- [转]Hive开发经验问答式总结
本文转载自:http://www.crazyant.net/1625.html 本文是自己开发Hive经验的总结,希望对大家有所帮助,有问题请留言交流. Hive开发经验思维导图 Hive开发经验总结 ...
- flask渲染模板时报错TypeError: 'UnboundField' object is not callable
渲染模板时,访问页面提示TypeError: 'UnboundField' object is not callable 检查代码,发现实例化表单类是,没有加括号:form = NewNoteForm ...
- 【Alpha版本】冲刺阶段——Day3
[Alpha版本]冲刺阶段--Day3 阅读目录 今日进展 问题困难 明日任务 今日贡献量 TODOlist [今日进展] 密码算法方面: 参考了md5/sha1+salt和Bcrypt后,我们决定使 ...
- SQL Server 2008 R2 常用系统函数学习
/******************************************* * 聚合函数 *******************************************/ SEL ...
- Python进阶【第二篇】编写Python代码
一.第一句Python代码——Hello Word 在 /home/dev/ 目录下创建 hello.py 文件,内容如下: print "hello,world" 执行 hell ...
- 2019/3/19 wen 运算符
- List,Set,Collection,Collections比较
官方话 1.List和Set都是接口,他们都继承于接口Collection,List是一个有序的可重复的集合,而Set的无序的不可重复的集合.Collection是集合的顶层接口,Collection ...