《汇编语言程序设计》(双语)上机指导... 1
实验1 建立windows环境下32位汇编语言开发环境... 2
实验2 Instruction Format and Addressing Mode. 3
实验3 Data Operation Programming. 4
实验4 Branching and Loop Programming. 5
实验5 Procedure Programming. 7
实验6 Input/Output Programming. 9
实验7 Macro Design. 10
实验8 Mixed Programming. 11
调试程序Windbg. 18
宏汇编命令ML和连接命令LINK常用参数速查... 21
输入输出宏命令... 22
实验目的:建立windows环境下32位汇编语言开发环境,并熟悉它的使用方法。
实验要求: (1)建立windows环境下32位汇编语言开发环境;
(2)熟悉自己建立的开发环境的使用方法;
实验内容: (1)定制masm32集成开发环境,使之符合教学要求。
(2)分别建立汇编,连接,和汇编&连接批处理命令,能够生成包含调试信息的目标文件,列表文件,以及能够进行调试的可执行WIN32控制台程序。
(3)建立32位汇编语言框架程序。
(4)在自己建立的开发环境下汇编,连接,运行教材中的fig3-1。
实验步骤:
1、定制开发环境masm32
修改文件msm32\bin\buildc.bat中的内容,使得执行Project\Console Assemble & Link后能够汇编连接可调试的32位控制台应用程序,同时生成列表文件。
汇编命令改为:
\masm32\bin\ml /c /coff /Fl /Zi “%1.asm”
连接命令改为:
\masm32\bin\link /debug “%1.obj”
2、在定制后的masm32开发环境中运行教材中的例题fig3-1.
3、利用教材提供的80x86/software在命令行方式下运行例题fig3-1.
4、建立适合在定制开发环境下使用的32位应用程序框架
参考:
.386 ;必须是第一条非注释语句,说明这是一个32位应用程序
.model flat, stdcall ;定义程序的存储模式(32位应用程序中必须采用flat)
include \masm32\include\io32.inc ;可选,如果在程序中使用作者自定义的宏命令需要这一句
.stack 4096 ;定义堆栈段
.data ;定义数据段
…… ;数据定义
.code ;定义代码段
start: ;程序起始点
…… ;程序代码
ret ;程序结束点,返回WINDOWS
…… ;子程序代码
end start ;汇编结束
5、在自己建立的开发环境下实现教材中P59. Programming Exercises 3.3中第3题。
实验要求:完成实验报告。在实验报告中完成下列内容:
(1)写出你自己的32位应用程序框架,并说明如何汇编,连接生成可执行文件。
(2)写出实验步骤5中程序的完整源代码。
实验目的:熟悉汇编语言指令格式,掌握常用数据定义伪指令,理解各种寻址方式的应用。掌握调试工具Windbg.exe的使用。
实验要求: (1)通过调试程序理解常用数据定义伪指令的作用。
(2)通过调试程序理解各种寻址方式的应用。
(3)熟练掌握调试工具Windbg的使用方法。
实验内容:(1)上机汇编连接fig3-1,生成并观察列表文件;用调试工具Windbg单步执行程序,观察寄存器和内存的变化。
(2)编写程序完成教材中P72. Exercises3.5。用Windbg观察内存的分配情况。
实验步骤:
1、 上机汇编连接fig3.1
(1) 查看列表文件。根据列表文件画出数据段中数据的分配情况。
(2) 用Windbg调试fig3-1。用memory窗口察看prompt1开始的内存空间,并记录下来。
(3) 对比源程序中的数据定义,列表文件的数据分配和在Windbg中记录的数据,理解数据定义伪指令的作用。
2、 用Windbg调试fig3-1,用Disassembly窗口察看指令的机器码。
3、 用Windbg单步执行fig3-1,观察每一条指令的执行结果。
4、 上机编写完整的源程序加入教材中P72. Exercises3.5中的数据定义,汇编连接后,用Windbg观察内存分配的情况。
实验要求:完成实验报告,回答下面的问题:
1、 要使程序能在windbg中调试,执行汇编和连接命令时,需要使用什么参数?
2、 Fig3-1.exe中执行指令input string, 40时,用户如果输入”123”, 该指令的执行结果是什么?atod string指令执行后的结果是什么?
3、 写出P72. Exercises3.5中1,3,5,7,10,12,15,17,23,32定义的内存空间的值。
4、 写出下列指令的寻址方式和机器码:
(1) add eax, number1
(2) mov number1, eax
(3) mov eax, 100
(4) mov ebx, offset number1
add eax, [ebx]
实验目的:熟练掌握基本的数据传送指令,算术运算指令和位操作指令在编程中的应用。
实验要求:按照要求编写程序,调试运行。
实验内容:
1、 完成教材P107. Programming Exercises 4.2中第2题。Write a complete 80x86 assembly language program to prompt for values of x,y,and z and display the value of expression 2(-x+y-1)+z. Allow for 32-bit integer values.
2、 完成教材P117. Programming Exercises 4.3中第3题。Suppose that someone has a certain number of coins(pennies, nickels,dimes,quarters,fifty-cent pieces, and dollar coins) and wants to know the total value of the coins, as well as how many coins there are. Write a program to help.
3、 完成教材P129. Programming Exercises 4.4中第4题和第5题。
a) Write a complete 80x86 assembly language program to prompt for four pairs of grades and weighting factors. Each weighting factor indicates how many times the corresponding grade is to be counted in the sum. The weighted sum is: WeightedSum=Grade1*Weight1+ Grade2*Weight2+ Grade3*Weight3+ Grade4*Weight4 and the sum of the weight is: SumWeights=Weight1+Weight2+Weight3+Weight4. Display the weighted sum, the sum of the weights and the weighted average(WeightedSum/SumofWeights).
b) Write a complete 80x86 assembly language program to prompt for four grades , and then display the sum and the average of the grades in ddddd format.
4、 编写代码实现下面的功能:无符号两位十进制字符串转换为对应的二进制数存入AL
5、 编写代码实现下面的功能:将AL中的数值(0-99)转换为无符号十进制数字符串。
6、 编写代码实现下面的功能:将两位的十六进制字符串(0-9)转换为对应的二进制数存入AL
7、 编写代码实现下面的功能:将AL中的数值转换为对应的两位十六进制字符串。
实验要求:提交试验内容1-3源程序,完成实验报告。实验报告中要求写出实现实验内容4,5,6,7的关键代码。
实验目的:熟练掌握分支和循环结构的设计方法,熟悉跳转和循环指令的使用方法。
实验要求:按照要求编写程序,调试运行。
实验内容:
1、 编写程序实现下面的算法:
if
then
lowerCount+1;
else
if(ch≥’A’) and (ch≤’Z’)
then
upperCount+1
else
otherCount+1;
endif
endif
其中ch调用ReadChar输入,lowerCount, upperCount和otherCount的值用WriteUDecByte显示。
2、 编写程序从键盘输入一系列有符号数,找出其中的最大数和最小数,显示运行结果。建议算法如下:
显示 “First number?”;
调用ReadSDecDword输入双字有符号数;
minimum:=number;
maximum:=number;
while(显示 “Another number?(Y or N)”)loop
if (输入Y) then
调用ReadSDecDword输入双字有符号数;
if(number
then
minimum:=number;
endif
if(number>maximum)
then
maximum:=number;
endif
endwhile
3-6题中任选一题:
3、编写程序将EAX的内容转换为二进制字符串
4、编写程序将EAX的内容转换为十六进制字符串
5、编写程序将EAX的内容转换为无符号十进制字符串
6、编写程序将EAX的内容转换为有符号十进制字符串,负数字符串以“-“引导。
7-10题中任选一题:
7、编写程序将二进制字符串表示的数据存入EAX寄存器
8、编写程序将十六进制字符串表示的数据存入EAX寄存器
9、编写程序将十进制字符串表示的无符号数据存入EAX寄存器
10、编写程序将十进制字符串表示的有符号数据存入EAX寄存器
实验要求:提交实验内容1,2的源程序,完成实验报告,实验报告中给出3-6题中任一题的关键代码,7-10题中任意一题的关键代码。
实验目的:理解堆栈的工作原理,熟练掌握子程序的设计方法,熟悉子程序相关指令的使用方法。
实验要求:按照要求编写程序,调试运行。
实验内容:
1、 上机调试下面的代码,单步执行,观察ESP寄存器和EIP寄存器内容的变化情况。观察esp指示的内存单元的内容。画出堆栈的变化过程,标注ESP寄存器的变化情况。
.386 ;必须是第一条非注释语句,说明这是一个32位应用程序
.model flat, stdcall ;定义程序的存储模式(32位应用程序中必须采用flat)
.code ;定义代码段
start: ;程序起始点
push 100
call subproc;程序代码
pop eax
ret ;程序结束点,返回WINDOWS
subproc proc
ret
subproc endp
end start ;汇编结束
2、编写完整的32位应用程序:设计子程序完成下面的功能, 在主程序中先调用ReadUDec输入数据,然后调用自己编写的子程序,将输入的数据转换为对应的可显示字符串的形式,最后调用WriteString显示转换后的字符串。要求完成的子程序可以在(1)-(4)中任选一题,(5)-(8)中任选一题。
(1)编写子程序将EAX的内容转换为二进制字符串
(2)编写子程序将双字补码转换为十六进制字符串
(3)编写子程序将EAX的内容转换为无符号十进制字符串
(4)编写子程序将双字补码转换为有符号十进制字符串,负数字符串以“-“引导。
(5)编写子程序将二进制字符串表示的数据存入EAX寄存器
(6)编写子程序将十六进制字符串表示的数据存入EAX寄存器
(7)编写子程序将十进制字符串表示的无符号数据存入EAX寄存器
(8)编写子程序将十进制字符串表示的有符号数据存入EAX寄存器
3、利用多模块设计方法实现上面程序的功能,建立子程序库,并编写主程序调用子程序库中的函数。
提示: (1) 编写子程序模块完成上题中的子程序功能,汇编生成目标文件。
(2) 将子程序目标文件组成库文件:
\masm32\bin\lib 目标文件名 /out:库文件名
或者\masm32\bin\link -lib 目标文件名 /out:库文件名
(3) 编写主程序模块: 用extern声明外部子程序,用includelib包含前面生成的库文件,在主程序中先调用ReadUDec输入数据,然后调用自己编写的子程序,将输入的数据转换为对应的可显示字符串的形式,最后调用WriteString显示转换后的字符串。汇编连接生成可执行文件。
实验要求:提交实验内容3的源程序,并在实验报告中说明子程序库的开发过程,以及可执行程序的执行结果;实验报告中给出实验内容3中子程序源代码(可以在(1)-(4)中任选一题,(5)-(8)中任选一题。)
实验目的:熟练掌握实现实模式和保护模式下键盘输入和屏幕显示功能的程序设计方法。
实验要求:按照要求编写程序,调试运行。
实验内容:
1、编写实模式应用程序:利用IN/OUT指令读写CMOS时钟,显示当前的日期和时间。
2、编写实模式应用程序:利用IN/OUT指令编写简单的音乐程序。运行时,当用户按下按键1-7,分别演奏音调dou,re,mi,fa,so,la,si
3、编写完整的16位应用程序:设计子程序完成下面的功能, 在主程序中先调用输入字符串的子程序,将字符串中所有英文字符变为大写,其他字符不变。最后调用输出字符串的子程序,显示原始字符串和转换后的字符串。
(1) 编写实模式子程序利用系统调用完成键盘输入一个字符。
(2) 编写实模式子程序利用系统调用完成屏幕显示一个字符。
(3) 编写实模式子程序利用系统调用完成键盘输入一个字符串。
(4) 编写实模式子程序利用系统调用完成屏幕显示一个字符串。
4、编写完整的32位应用程序:设计子程序完成下面的功能, 在主程序中先调用输入字符串的子程序,将字符串中的字符逆序排序生成新的字符串。最后调用输出字符串的子程序,显示原始字符串和转换后的字符串。编写保护模式子程序利用系统调用完成键盘输入一个字符。
(1) 编写保护模式子程序利用系统调用完成键盘输入一个字符。
(2) 编写保护模式子程序利用系统调用完成屏幕显示一个字符。
(3) 编写保护模式子程序利用系统调用完成键盘输入一个字符串。
(4) 编写保护模式子程序利用系统调用完成屏幕显示一个字符串。
实验要求:提交第2题源程序;在实验报告中给出第3(3)和(4)题和第4(3)和(4)题的关键代码。
实验目的:熟练宏的使用方法。
实验要求:按照要求编写程序,调试运行。
实验内容:
1、编写完整的32位应用程序:先定义下面的宏,然后在程序中调用宏,生成列表文件。根据列表文件写出宏扩展后的结果。
(1) 定义Move32宏接收两个内存操作数,把源操作数送到目的操作数。
(2) 定义Mult32宏接收两个内存操作数,将他们相乘产生一个32位的乘积。
2、 编写一个ReadUdec的宏,从标准输入上读取一个8位,16位或32位的无符号整数,并在给定的参数中返回。使用条件操作符允许宏能够处理不同大小的输入参数。写一个程序调用宏并传递不同尺寸的操作数。
3、 编写一个WriteUdec的宏,通过调用显示无符号数的功能在标准输出上显示一个无符号数。传递给宏的参数可以是一个字节、字或双字,在宏内使用条件操作符以便能适应不同尺寸的参数。写一个程序调用宏,并传递给宏不同尺寸的参数。
实验要求:提交1,2,3源程序,在实验报告中写出它们的宏定义方法和宏调用方法。
实验目的:熟练掌握汇编语言与VC++的混合编程的方法。
实验要求:按照要求编写程序,调试运行。
实验内容:
1. 编写一个C++程序通过调用汇编子程序实现的功能。
提示:在C程序中输入两个整数,然后调用汇编子程序对这两个数求积,在主程序中打印计算结果。编程并上机调试通过。
2. 编写程序,在汇编程序中初始化varA=12、varB=6,调用C语言的子程序求积并打印计算结果。编程并上机调试通过。
3. 将排序子程序改写成C语言的嵌入式汇编函数;然后编写一个C语言主程序,提供待排序的数据和显示排序后的结果。
4. 将排序子程序改写成可供C语言调用的模块;然后编写一个C语言主程序,提供待排序的数据和显示排序后的结果。
5. 编写识别CPU的汇编语言过程,供Visual C++6.0调用的形式,然后编写一个Visual C++主程序,并上机调试通过。
实验要求:完成实验报告,在实验报告中写出1,3,4的关键代码,并写出运行结果
附录:
Windows环境下32位汇编语言开发环境的建立
在Windows环境下进行汇编语言程序设计之前,首先需要搭建一个汇编语言的开发环境。现在汇编语言开发工具包常见的是MASM,TASM和NASM。MASM是微软开发的宏汇编工具,适合在Windows环境下进行程序设计,性能稳定,持续升级;NASM的语法与MASM略有不同,它可以在不同的环境下使用,LINUX或Windows。鉴于目前汇编语言程序设计教学中更多的选择了MASM,本文将介绍基于MASM的32位汇编开发环境的几种搭建方法。其他汇编工具的具体内容可参考相关的手册。
汇编语言的开发分为源代码编辑,汇编和连接三个步骤,在必要的时候还需要对程序进行调试。因此汇编语言开发环境中应包含编辑软件,汇编软件,连接软件和调试软件。如果将这些软件集成在一起就是构成一个集成开发环境。
一、命令行环境
首先下载一个MASM615开发工具包。在许多汇编网站和汇编教材的配套光盘中都提供了该工具包。根据提示,进行安装。然后就可以用它来开发汇编程序。
(1)源代码编辑
汇编源程序是纯文本文件,其扩展名为.asm,可以用任何一种文本编辑软件来编写汇编原代码。比如EditPlus,UltraEdit,NotePad,Word, VC++等,注意文件保存的时候必须以纯文本格式保存,并取.asm后缀名。
(2)汇编
源文件不能直接被机器执行,需要运行汇编软件对它进行汇编生成目标文件,后缀为.obj.,这是一个二进制文件。如果出现语法错误,汇编程序会产生错误报告,程序员可以根据这些错误报告对源程序进行重新编辑,重新汇编,直到没有语法错误为止。
MASM汇编器的命令是ml.exe,其命令行格式为:
Ml [/option] 源文件 [/link option]
生成32位应用程序时,常用的命令行是:
ML /coff /c /Fl /Zi filename;
例如,要汇编test.asm源文件,生成coff格式的目标文件,列表文件和调试信息,可以使用命令行:
ML /coff /c /Fl /Zi test.asm;
为了避免每次汇编源文件的时候都要输入许多参数,可以建立一个批处理文件。例如批处理文件mlbat.bat
@echo off
if exist "%1.obj" del "%1.obj"
if exist "%1.exe" del "%1.exe"
path\ml /c /coff /Fl /Zi "%1.asm"
if errorlevel 1 goto errasm
:errasm
echo _
echo Assembly Error
goto TheEnd
:TheEnd
pause
有了这个批处理文件以后,如果汇编test.asm,就可以用命令:
mlbat test
在建立自己批处理文件的时候,可以根据需要设定参数,指定路径。
(3)连接
目标文件仍然不能执行,还需要运行连接程序,将目标文件和库文件连接起来,才能生成最后可以执行的.exe文件。
生成可执行文件的工具叫做连接器。在前面提到的汇编语言开发工具包中都包含有连接器link.需要注意的是,连接器有两种:一种是16位连接器(Segmented Executable Linker),用于生成DOS程序,一种是32位连接器,可以生成Win32PE文件(Incremental Linker),如果要生成32位应用程序需要使用后者。在MASM8和VC中提供有32位连接程序。一般来说,在开发工具包中用link16和link32分别表示16位和32位连接软件。
连接器的命令行用法为:
LINK [option] filename
生成windows控制台程序的常用命令是:
LINK /subsystem: console /DEBUG filename
生成windows程序的常用命令是:
LINK /subsystem: windows /DEBUG filename
参数/DEBUG是为方便调试而设置的。
例如,将前面生成的目标文件test.obj连接生成控制台程序test.exe所用的命令行是:
LINK /subsystem:console /DEBUG test.obj
为了避免每次连接的时候都要输入许多参数,同样也可以建立一个批处理文件。例如批处理文件linkbat.bat
@echo off
if not exist “%1.obj” goto errlink
path\Link /SUBSYSTEM:CONSOLE /OPT:NOREF /DEBUG "%1.obj"
if errorlevel 1 goto errlink
:errlink
echo _
echo link Error
goto TheEnd
:TheEnd
pause
此时,对test.obj连接,可以用命令:
linkbat test
在建立自己批处理文件的时候,可以根据需要设定参数,指定路径。
如果建立一个类似VC里build的命令,就可以执行一个命令对原程序进行汇编和连接。下面的批处理文件buildc.bat执行的就是先汇编再连接的功能:
REM buildc.bat
@echo off
if exist "%1.obj" del "%1.obj"
if exist "%1.exe" del "%1.exe"
path\ml /c /coff "%1.asm"
if errorlevel 1 goto errasm
path\Link /SUBSYSTEM:CONSOLE /OPT:NOREF "%1.obj"
if errorlevel 1 goto errlink
dir "%1.*"
goto TheEnd
:errlink
echo _
echo Link error
goto TheEnd
:errasm
echo _
echo Assembly Error
goto TheEnd
:TheEnd
pause
执行命令:buildc test
就会对test.asm进行汇编,并生成windows控制台程序test.exe.
(4)调试
生成的.exe文件执行后完成的功能如果与预想的功能不相符,说明程序编写出现了逻辑错误,程序员需要对原程序进行检查,找出错误。检查逻辑错误可以阅读原程序,通过分析逻辑算法找出错误;也可以在程序中适当的位置添加输出语句,显示中间结果来发现错误,还可以利用调试软件,跟踪程序的执行,动态调试程序从而发现错误。
调试器有两大类,用户模式和内核模式。用户模式的调试器用于调试用户模式的应用程序,工作在Ring3级,如vc自带的调试器和Windbg;内核模式的调试器则可以调试操作系统内核,处于CPU和操作系统之间,工作在Ring0级,如SoftICE, OLLYDBG, trw2000。关于调试器的使用方法,将在另外的文章中讨论。
二、集成开发环境
开发一个汇编程序需要经过上述四步才能生成正确的可执行文件。程序员可以下载安装汇编语言开发工具包,然后就可以进行程序开发。如果需要更加方便的执行汇编和连接的步骤,建议自己建立批处理文件,避免每次命令行输入许多参数。也可以使用集成开发环境将上述步骤放在一个界面下方便的完成。WINDOWS环境下常用的集成开发环境有MASM32和Visual C++,VisualAsm,PASS32,GASM。下面介绍MASM32和Visual C++的在开发汇编语言程序时的用法。
1、 MASM32
MASM32是Windows环境下的窗口应用程序,集成了微软的MASM工具,包含丰富的库函数和宏文件以及相应的联机帮助,用户界面友好,可以很方便的进行WINDOWS下汇编程序的开发,基本不需要进行额外的设置。
下载安装MASM32之后,将Qeditor图标拖到桌面上以方便以后的使用。
单击Qeditor图标启动MASM32,在主窗口中输入源代码,选择File/Save保存文件。然后再选择Project菜单下的命令进行汇编和连接。该菜单中主要使用的命令有:
Assemble ASM file:汇编生成32位应用程序,对应的批处理文件是masm32\bin\assembl.bat.
Link OBJ file : masm32\bin\lnk.bat
ASSEMBLE & link : BUILD.BAT
BLDALL:BUILDALL.BAT
Link OBJ file : masm32\bin\lnkC.bat
ASSEMBLE & link : BUILDC.BAT
BLDALL:BUILDALLC.BAT
这些批处理文件的内容都与前面所讲的汇编和连接批处理的内容类似,读者可以根据需要修改这些命令。
MASM32将编辑,汇编和连接很好的结合在一起,对于windows图形界面的变成也非常方便,它提供了一个资源编辑器。窗口应用程序可以在该环境中直接运行,但是控制台程序则需要启动命令行方式窗口运行。
2、 Visual C++ 6.0
VC是微软开发的C++ 6.0的集成开发环境,在安装了MASM615之后,也可以用作汇编语言程序开发的集成环境。有两种方法可以用VC来开发汇编程序。
方法1:
启动VC++后,从菜单中选择“File”-〉New
在New对话框的标签中选择Projects,再选中Win32 Console Application,在Location中选择路径,并在Projectname中输入名字,例如test。VC在指定的路径自动建立test文件夹。
单击OK,在接下来的对话框中选择An Empty project,单击Finish。
在左面的列表窗口的下面选择FileView标签,列出当前project中的文件,现在没有文件在projects中。
单击新建按钮,在右侧的编辑窗口中输入汇编源程序,存盘到test目录下,命名为test.asm。
在左侧的窗口右击SourceFiles,出现的快捷菜单中,选择Add files to projects…,在文件选择对话框里选择文件test.asm,OK,这时,在Source Files下出现test.asm的名字。右击该文件名,出现快捷菜单,选择setting三…,在对话框右边的Commands内输入ml /c /coff test.asm,Outputs内输入test.obj,单击Ok,将ML.exe和ml.err复制到windows目录。按F7,自动编译生成test.exe.
编译和连接信息显示在Output视图中。接下来可以直接在VC环境中运行和调试该程序。
方法2:
打开VC++。点取File->New命令,新建一个Workspace,命名如testmak,右击工作区名字,选择加入新工程命令,在工作区中加入一个makefile工程。该工程文件与工作区在同一个文件夹中。
建立一个make文件testmak.mak加入工程中:
LINK32=link.exe
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"\testmak.pdb" /debug /machine:I386 /out:".\testmak.exe" /pdbtype:sept
LINK32_OBJS= \
".\testmak.obj"
".\testmak.exe" : $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
SOURCE=.\testmak.asm
InputPath=.\testmak.asm
".\testmak.obj" : $(SOURCE)
<
ml /c /coff /Zi testmak.asm
<<
下面建立一个汇编源文件testmak.asm加入工程文件的源文件夹中:
.386
.model flat, stdcall
option casemap:none
includelib msvcrt.lib
printf PROTO C: ptr sbyte, :vararg
.data
szMsg byte "hello world!",0ah,0
.code
start:
invoke printf, offset szMsg
ret
public start
end start
最后设置可执行文件,库和包含文件的路径选择TOOLS->OPTIONS- >DIRECTORIES,在Executable中加入路径C:\MASM615,在Include中加入C:\MASM615\INCLUDE ;在library的路径中加入C: \MASM615\LIB 。
如果一切正常,下面就可以选build命令F7,生成你的可执行文件了。如果没有错误单击执行按钮,可以看见执行的结果。
在VC中开发汇编程序建立工程时的设置工作稍显繁琐,但是一旦设置好后,开发的四个步骤一气呵成,在进行多模块设计的时候,这是一个很好的选择。
(附注:本文中的示例程序都与testmak.asm一样。)
WinDbg是微软开发的免费源码级图形界面调试工具,可以调试Win32应用程序,服务器应用程序调试和Kernel模式驱动调试。本文介绍Windbg在调试Win32应用程序时的常用命令。
1、 Windbg的启动
Windbg可以从命令行启动,启动命令格式为:
windbg [-a] [-g] [-h] [-i] [-k [platform port speed]] [-l[text]]
[-m] [-p id [-e event]] [-s[pipe]] [-v] [-w name] [-y path]
[-z crashfile] [filename[.ext] [arguments]]
在WindowsXP/2000操作系统下,可以直接双击Windbg图标启动。
2、 打开应用程序
被调试的应用程序在汇编和连接时应加入调试信息。汇编时使用参数/Zi;连接程序使用参数/debug。
开始调试一个应用程序时,首先选择File菜单下的Open Executable命令,在对话框中选择可执行文件。出现Command 窗口,点击工具栏按钮后,在Command 窗口中显示一组信息,再次点击按钮后,在Command 窗口后出现Source窗口。
3、显示存储单元
显示存储单元的按钮是。点击该按钮后,出现对话框
在Address Expression编辑框中填入要察看的地址信息。地址信息有两种常用的输入方式:
(1)指定内存单元地址
例如:在Address Expression 中填入0x0040103f,点击按钮OK后出现指定地址开始的内存单元的内容:
其中0x0040103F至0x004010BF是Windbg显示以十六进制表示的单元地址,中间用十六进制表示每个字节,右边用ASClI字符表示每个字节。
(2) 通过变量名表示
例如:在Address Expression 中填入&b_var1,点击按钮OK后出现b_var1开始的内存单元的内容:
其中0x00404000地址是变量b_var1所在的单元。
随着程序的执行,相应内存单元的内容会相应变化。
4、 显示寄存器内容
显示寄存器内容的按钮是,点击该按钮后,出现窗口
其中EFL是标志寄存器内容,对应每一位判断标志位的值。EA是内存寻址方式指示的有效地址。
随着程序的执行,寄存器的内容会相应变化。
5、 运行程序
运行程序按钮是。从应用程序入口地址开始执行程序,遇到断点停止。
6.单步执行程序,
单步执行程序有两种类型:
(1) Stepinto
单步执行命令,当遇到子程序调用指令时,进入子程序内部逐条执行指令。
(2) Step over
单步执行命令,当遇到子程序调用指令时,不进入子程序内部逐条执行指令,而把调用子程序当作一条指令执行。
7.反汇编命令U(Unassemble)
该命令执行后,出现窗口:
窗口中的内容从左至右依次是:地址,机器码,指令。随着程序的执行,反汇编窗口也随之变化。
8、Watch窗口
点击按钮后出现空白的Watch窗口:
在左边的一列中输入变量的名字,右边显示变量的值:
随着程序的执行,变量的值会相应变化。
11> 退出Windbg
选择File菜单中的Exit命令,可以退出Windbg。
宏汇编命令ML.EXE的命令行格式如下:
ML [/参数选项] 文件列表 [/LINK 连接参数选项]
ML允许汇编和连接多个程序形成一个可执行文件;它的常用参数选项如下,注意参数是大小写敏感的):
/AT——允许tiny存储模式(创建一个COM文件)
/c——只汇编源程序,不进行自动连接(这里是小写的字母c)
/Fl 文件名——创建一个汇编列表文件(扩展名LST)
/Fr 文件名——创建一个可在PWB下浏览的.SBR源浏览文件
/Fo 文件名——根据指定的文件名生成模块文件,而不是采用缺省名
/Fe 文件名——根据指定的文件名生成可执行文件,而不是采用缺省名
/Fm 文件名——创建一个连接映象文件(扩展名MAP)
/I 路径名——设置需要包含进(INCLUDE)源程序的文件的所在路径
/Sg——在生成的列表文件中,列出由汇编程序产生的指令
/Sn——在创建列表文件时不产生符号表
/Zi——生成模块文件时,加入调试程序CodeView需要的信息
/Zs——只进行句法检查,不产生任何代码
/LINK——传递给连接程序LINK的参数
/nologo——展开版权信息
/Bl ——连接器名字—— 使用其它连接器
/Sa—— 列表文件最大限度展开源码
/Sc—— 在创建列表文件时加入时间信息
/Cp—— 区分用户自定义标识符的大小写
/Sf—— 生成第一次汇编列表
/Cu ——所有标识符转换为大写
/Sl
/Cx——保留PUBLIC 和EXTERN变量的大小写
/Sn—— 展开符号表列表
/coff——生成COFF格式的文件
/Ta 文件名 ——汇编不是以ASM为扩展名的源文件
/WX ——警告信息被看作错误信息
/W——
/Zd ——在调试信息中加入行号
/Zf ——所有符号成为公有符号
/G
/Zi ——加入符号调试信息
/I
连接命令LINK.EXE的命令行格式如下:
LINK [/参数选项] 文件列表
LINK连接一个或多个程序形成一个可执行文件;它的常用参数选项如下,
/COMMENT:注释信息——加入注释信息
/DEBUG——加入调试信息
/DEBUGTYPE:{CV|COFF}——指定调试信息类型
/DEFAULTLIB:library——指定默认库文件
/DLL——创建DLL文件
/DRIVER[:{UPONLY|WDM}]——创建驱动程序
/ENTRY:标号——设置程序入口
/EXPORT:symbol——定义可以被其他模块使用的符号
/INCREMENTAL:{YES|NO}——是否为增式连接器
/LIBPATH:dir——指定库文件的路径
/MAP[:filename] ——映像文件
/OUT:filename——定义生成文件名
/SUBSYSTEM:{NATIVE|WINDOWS|CONSOLE|WINDOWSCE|POSIX}——指定操作系统类型
本表中所列出的宏命令是作者自己定义的输入输出宏,它们的定义在文件io16.inc和io32.inc中。如果在实模式的应用程序中,加入INCLUDE io16.inc才可以使用这些宏;如果在保护模式的32位应用程序中,加入INCLUDE io32.inc才可以使用这些宏。
宏命令 |
格式 |
功能 |
ReadBinByte |
ReadBinByte b_var |
读入二进制字节数据存放到字节类型参数b_var中 |
ReadBinWord |
ReadBinWord w_var |
读入二进制字数据存放到字类型参数w_var中 |
ReadBinDword |
ReadBinDword d_var |
读入二进制双字数据存放到双字类型参数d_var中 |
ReadHexByte |
ReadHexByte d_var |
读入十六进制双字数据存放到双字类型参数d_var中 |
ReadHexWord |
ReadHexWord w_var |
读入十六进制字数据存放到字类型参数w_var中 |
ReadHexDword |
ReadHexDword b_var |
读入十六进制字节数据存放到字节类型参数b_var中 |
ReadUDecByte |
ReadUDecByte b_var |
读入无符号十进制字节数据存放到字节类型参数b_var |
ReadUDecWord |
ReadUDecWord w_var |
读入无符号十进制字数据存放到字类型参数w_var |
ReadUDecDword |
ReadUDecDword d_var |
读入无符号十进制双字数据存放到双字类型参数d_var |
ReadSDecByte |
ReadSDecByte b_var |
读入有符号十进制字节数据存放到字节类型参数b_var |
ReadSDecWord |
ReadSDecWord w_var |
读入有符号十进制字数据存放到字类型参数w_var |
ReadSDecDword |
ReadSDecDword d_var |
读入有符号十进制双字数据存放到双字类型参数d_var |
ReadChar |
ReadChar char |
读入字符,其ASCII码存放到字节类型参数char |
ReadString |
ReadString buffer |
读入字符串,字符串输入以回车结束,输入的字符串存放到buffer指向的内存空间。 |
WriteString |
WriteString string |
显示以0结尾的字符串string.字符串的长度不超过128。 |
WriteBinByte |
WriteBinByte b_var |
显示二进制字节数据b_var |
WriteBinWord |
WriteBinWord w_var |
显示二进制字数据w_var |
WriteBinDword |
WriteBinDword d_var |
显示二进制双字数据d_var |
WriteHexByte |
WriteHexByte b_var |
显示十六进制字节数据b_var |
WriteHexWord |
WriteHexWord w_var |
显示十六进制字数据w_var |
WriteHexDword |
WriteHexDword d_var |
显示十六进制双字数据d_var |
WriteUDecByte |
WriteUDecByte b_var |
显示无符号十进制字节数据b_var |
WriteUDecWord |
WriteUDecWord w_var |
显示无符号十进制字数据w_var |
WriteUDecDword |
WriteUDecDword d_var |
显示无符号十进制双字数据d_var |
WriteSDecByte |
WriteSDecByte b_var |
显示有符号十进制字节数据b_var |
WriteSDecWord |
WriteSDecWord w_var |
显示有符号十进制字数据w_var |
WriteSDecDword |
WriteSDecDword d_var |
显示有符号十进制双字数据d_var |
WriteChar |
WriteChar char |
显示字符char |
影子妞加油~
=S=