本篇需要掌握的:
- 对汇编语言构成的基本要素有所了解
- 能对课本上简单的汇编例程进行修改和测试
- 掌握ml 和 link 即汇编和链接命令的使用
- 掌握windbg的基本使用
汇编语言的基本要素
- 格式汇编语句具有如下格式:
名字 助记符 操作数 ;注释 (其中一些项是可选的。) - 三种汇编语句的类型:
- 指令性语句-每一条语句对应一条CPU指令
- 指示性语句-告诉汇编器需要做什么
- 宏-展开为其他语句
- 三种操作数的模式:
- 立即数-指令中含有数据
- 寄存器-数据在寄存器中
- 存储器-数据在存储区域
- 得到存储器操作数的两种方式:
- 直接寻址-地址在指令中给出
- 间接寻址-数据的地址在寄存器中
- IO.H定义了一些输入输出宏,这些宏调用了一些汇编到了IO.OBJ中的过程:
- output
- input
- atod 转换一字符串为一双字长的2进制补码数
- dtoa 转换一双子长的2进制补码数为一字符串
- atoi 转换一字符串为一字长的2进制补码数
- itoa 转换一字长的2进制补码数为一字符串
宏名 | 源操作数 | 目的操作数 | 受影响的标识位 | 功能 |
---|---|---|---|---|
dtoa | 双字寄存器或存储器 | 存储器 | 无 | 双字节数转换为11字节长的ASCII码 |
atod | 存储器 | 无 | 如果输入错误,OF置1否则OF值0,其他标志的值根据结果存入EAX寄存器 | 将源操作数中字符串中的数字字符作为一个整数并存入EAX寄存器,非数字字符存入ESI寄存器 |
itoa | 单字节寄存器或存储器 | 存储器 | 无 | 单字节数转换为6字节长的ASCII码 |
atoi | 存储器 | 无 | 与atod相同 | 转换源操作数中的字符串为单字节数存入AX寄存器 |
程序的汇编链接和执行
*说明1:汇编的源程序通常存储在.ASM类型的文件中 *
说明2:以MASM6.1中的ML汇编器为例来汇编程序
说明3:如果想在除软件安装目录以外的文件夹下创建源文件,必须要将io.h,io.obj,kernel32.lib复制到此文件夹下并且设置一个软件目录的路径到你的path当中去
-
简单的汇编
ml /c /coff example.asm
其中/c说明只需要编译
/coff转换参数要产生一个公共对象文件格式(common object file format)
ML转换参数区分大小写,必须以小写形式输入 -
带调试信息的汇编
汇编成功时
ml /c /coff /Zi example.asm
/Zi告诉汇编器在输出时添加调试信息
-
用连接程序link产生可执行文件(后缀名:.exe)
link /debug /subsystem:console /entry:start /out:example.exe example.obj io.obj kernel32.lib
此命令将example.obj io.obj kernel32.lib三个文件链接起来,产生一个输出文件EXAMPLE.EXE.转换参数/subsystem:console告链接器生成一个在DOS环境下运行的控制台程序,转换参数/entry:start标识程序的入口点,/debug转换参数标识链接时生成调试程序 -
执行程序: 直接输入需执行的程序名(不需要带后缀)如example
-
查看列表文件(.lst)
生成列表文件ml /c /coff /Zi /Fl example.asm
/Fl提示汇编器输出时生成列表文件
个人认为这个对初学者来说并不是很重要,我就看不懂,但是并不妨碍我写代码和调试程序
该清单文件显示源代码,要转换的目标代码以及附加信息 -
使用调试软件winbg调试程序
1)打开Winbg程序 输入:winbg
2)搭建环境:-
在File菜单中打开“Open Executable…”后选择“example.exe”或其他可执行文件,标题栏中增加了example.exe,以及command窗口中还出现一些文字。再点击进入
step into 或F8
- 调试主窗口: 1步骤后出现信息窗口提示没有debugee的符号信息,点确定,再点进入,源代码就出现再Command窗口后面的子窗口中。
- 最小化Command窗口,选择View菜单,再选择Registers子菜单,打开一个窗口,用来显示80X86中寄存器的内容。
- 选择View菜单下Memory子菜单,打开一个窗口用来显示内存的内容,对于该窗口来说,必须输入内存的开始地址。开始地址即为.DATA后的(数据保留区的)第一项的地址 例如在
.DATA ; reserve storage for data number1 DWORD ? number2 DWORD ? prompt1 BYTE "Enter first number: ", 0 prompt2 BYTE "Enter second number: ", 0 string BYTE 40 DUP (?) label1 BYTE cr, Lf, "The sum is " sum BYTE 11 DUP (?) BYTE cr, Lf, 0
中使用&number1作为开始地址,这是数据段的第一项。
最后调整各个窗口大小,并且重新排列成方便调试和阅读的模式
这里是我最后的窗口效果
-
此时该程序的第一条语句高亮显示,每点一次step into即
,指令往下执行一条
- step over:跳过该条指令
- Run To Cursor: 执行到此时主窗口代码中光标所在的那一行(该行此时并未执行)
-
在File菜单中打开“Open Executable…”后选择“example.exe”或其他可执行文件,标题栏中增加了example.exe,以及command窗口中还出现一些文字。再点击进入
总结:
- 用记事本或这Notepad++等编辑工具书写源代码
- 汇编语言主程序的基本框架例程:
; Example assembly language program -- adds two numbers
; Author: R. Detmer
; Date: revised 7/97
.386
.MODEL FLAT
ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD
INCLUDE io.h ; header file for input/output
cr EQU 0dh ; carriage return character
Lf EQU 0ah ; line feed
.STACK 4096 ; reserve 4096-byte stack
.DATA ; reserve storage for data
.CODE ; start of main program code
_start:
INVOKE ExitProcess, 0 ; exit with return code 0
PUBLIC _start ; make entry point public
END ; end of source code
-
编译源代码
ml /c /coff /Zi example.asm
-
链接并生成example.exe(你自己使用时把example替换为你自己想生成的文件的文件名)
link /debug /subsystem:console /entry:start /out:example.exe example.obj io.obj kernel32.lib
注意: 其中example.obj 为链接时需要的经过汇编而成的obj文件,你需要将example改为你自己的源文件的文件名 -
使用windbg调试程序
-
在命令行中运行example.exe
example
网友评论