Win32汇编的环境和基础 (转)

news/2024/7/20 13:43:32 标签: 操作系统, 内存管理, 数据结构与算法
Win32汇编的环境和基础 (转)[@more@]
(罗云彬)

1.32位环境简介

在Dos下编汇 编程序,我们可以管理 系统的所有资源,我们可以改动系统中所有的 内存,如自己改动内存控制块来分配内存,自己修改中断向量表来截获中断等,对其他操作也是如此,如我们对键盘端口直接操作就可以把键盘屏蔽掉,可以这样来描述Dos系统:系统只有一个特权级别,在编程上讲,任何 程序和 操作系统都是同级的,所以在Dos下,一个编得不好的程序会影响其他所有的程序,如一个程序把键盘口中断关掉了,所有程序就都不能从键盘获得键入的数据,直到任何一个程序重新打开键盘为止,一个程序陷入死循环,也没有其他程序可以把它终止掉。Dos下的编程思路是“单任务”的,你只要认为你的程序会按照你的流程一步步的 执行下去,不必考虑先后问题(当然程序可能会被中断打断,但你可以认为它们会把环境恢复,如果中断程序没有把环境恢复,那是他们的错)。
内存管理方式上,Dos 汇编和 win32汇编也有很多的不同:Dos工作在实 模式下,我们可以寻址1M的内存,寻址时通过段寄存器来制定段的初始地址,每个段的大小为64K,超过1M的部分,就只能把他作为XMS使用,也就是说,只能用作数据存放使用而无法在其中执行程序。
而 windows在保护模式下执行,这里所有的资源对应用程序来说都是被“保护”的:程序在执行中有级别之分,只有操作系统工作在最高级--0级中,所有应用程序都工作在3级中(Ring3), 在Ring3中,你无法直接访问IO端口,无法访问其他程序运行的内存,连向程序自己的代码段写入数据都是 非法的,会在Windows的屏幕上冒出一个熟悉的蓝屏幕来。只有对Ring0的程序来说,系统才是全开放的。
在内存方面,Windows使用了 处理器的分页机制,使得对应用程序来说,所有的内存都是“平坦”的,你不必用一个段寄存器去指定段的地址,因为在保护模式下,段寄存器的含义是不同的(可以参见80386手册方面的书籍),你可以直接指定一个32位的地址来寻址4GB的内存。
在程序结构方面,Windows程序也有很大的不同,它是“基于消息”的,你可以想象这样一个常见的Windows窗口,上面有几个按钮,如果你用Dos编程的思路去考虑,你会发现实现它很困难:鼠标移动到窗口边缘时拖动会改变窗口大小,鼠标点击按钮时再做要做的事,你会发现,你的程序自开始执行后就在等待,你不知道鼠标先会点什么地方,实际上你是在等待所有可能的事情的发生。而在Dos下,你可以只顾自己先执行,需要 用户输入时,再停下来,你不输入我就不再执行,而且,我让你输入数据A你就不能输入数据B。
好了,言归正传,因为以上是Win32编程的基础,无论对Win32汇编还是VC++,它们都是一样的,下面我们来看看有关Win32汇编的内容。

2.Win32ASM 编译器

Win32ASM的编译器最常用的有两种:Borland公司的Tasm5.0和 microsoft的Masm6.11以上版本,两种编译器各有自己的优缺点,Tasm带了一个不大不小的Import库,而Masm没有带,但Masm在代码的 优化上面好象比Tasm做得好,但它却不带Import库。看来使用哪一种编译器还是比较难选择的,但Steve Hutchesson给了我们一个答案,他为Masm建立了一个很全的Import库,基本上包括了Windows绝大部分的 api 函数,这些库、include 文件和其他工具还有Masm6.14版本一起做成了一个 Masm32编译器 -- Masm32V5。这样一来,我们用汇编编程就象用C一样方便。
因为有了Masm32V5,所以就我个人而言,我推荐使用Masm作为Win32ASM的编译工具,但Masm和Tasm的宏语法有很多的不同,我的这个教程是以Masm格式写的。

3.Masm32的环境设置

在Win32编程中,由于Windows有很多的数据结构和定义,这些都放在include文件中,还有连接时要用到Import库(通俗的讲就是Windows提供的DLL文件中的函数列表,也就是告诉程序到哪里去 调用API函数),这些都放在include 和lib目录中。我们在编译时要指定以下的系统环境:

set include=Masm32v5Include
set lib=Masmv5lib
set path=Masmv5Bin

这样编译器就会到正确的路径中去找 include 文件和 lib 文件。你可以自己在 autoexec.bat 文件中加上以上语句,为了产生Windows的PE格式的执行文件,在编译和连接中要指定相应的参数:

编译: Ml /c /coff 文件名.asm
连接: Link /SUBSYSTEM:WINDOWS OBJ文件名.obj 资源文件名.res

为了不在每次编译时都要打这么多的参数,我们可以用 nmake 文件来代为执行,nmake 是代码维护程序,他会检查 .asm .obj .exe .res 等文件的时间,如果你 更新了源程序,他会自动执行编译程序或连接程序产生相应的文件。你可以在文件名为 makefile 的文件中指定使用的编译器和连接程序以及相应的参数,下面是一个 makefile 文件的例子:

NAME = Clock
OB js = $(NAME).obj
RES = $(NAME).res
$(NAME).exe: $(OBJS) $(RES)
Link /DE bug /SUBSYSTEM:WINDOWS $(OBJS) $(RES)
$(RES): $(NAME).rc
Rc $(NAME).rc
.asm.obj:
Ml /c /coff $(NAME).asm

文件告诉 nmake程序,程序名为 clock,产生 clock.exe 文件需要 clock.obj和 clock.res 文件,而产生 clock.res 文件需要 clock.rc 文件,产生 clock.obj 文件要用到 clock.asm 文件,至于是否需要执行 ml, link 和 rc,程序会根据文件的时间自动判断。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10790690/viewspace-951304/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10790690/viewspace-951304/


http://www.niftyadmin.cn/n/807352.html

相关文章

HashSet避免存储重复元素的原理

请参考:HashSet为什么不能存取重复元素?(底层图解详解) 以及:JAVA集合Set之HashSet详解

Creator之物理切割(第二部分)

摘要物理切割第二部分,切割多个物体,利用 Mask 切割图片!正文使用版本CocosCreator 版本 2.1.3最终效果多切割原理通过上一部分的教程,我们已经知道了单切割的原理,但是很显然,KUOKUO 的第一篇博客显得不通…

BMP位图文件结构及VC操作 (转)

BMP位图文件结构及VC操作 (转)[more]浙江工业大学 朱永辉---- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重,在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数显示BMP位图,可…

使用EasyMock对Servlet进行简单的测试

这是一个WebProject,但不需配置web.xml,因为EasyMock用不上它 首先是用到的实体类User.java package com.jadyer.model;public class User {private int id;private String username;private String password;/*-- 三个属性的setter和getter略 --*/publi…

如何跨越自我推销的难关?

在「 怎样做个无敌的程序员 」中聊到,除编程能力之外,程序员还要掌握销售能力。不管是推销自我,还是打造影响力,都离不开公众表达,特别是在行业峰会上侃侃而谈的演讲。公众演讲是程序员普遍不熟悉的领域,它…

互联网常见架构模式 之 nginx负载均衡

一:什么是Nginx Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like协议下发行。由俄罗斯的程序设计师Igor Sysoev所开发,供俄国大型的入口网站及搜索引擎Rambler&#x…

usr/bin/ld: cannot find 错误解决方法

参考:http://blog.siyebocai.cn/20100324_5p424qs7.html 通常在软件编译时出现的usr/bin/ld: cannot find -lxxx的错误,主要的原因是库文件并没有导入的ld检索目录中。 解决方式: 1。确认库文件是否存在,比如-l123, 在/usr/lib, /…

AccesS密码的打击 (转)

AccesS密码的打击 (转)[more]type TForm1 class(TForm) Button1: TButton; Chk2000: TCheckBox; Edit1: TEdit; Button2: TButton; Edit2: TEdit; OpenDialog1: TOpenDialog; Button3: TButton; Label1: TLabel; procedure Button1Click(Sender: Tobject); procedu…