Windows汇编语言程序设计基础
- 格式:doc
- 大小:240.50 KB
- 文档页数:25
Windows X86-64位汇编语言入门Windows X64汇编入门(1)最近断断续续接触了些64位汇编的知识,这里小结一下,一是阶段学习的回顾,二是希望对64位汇编新手有所帮助。
我也是刚接触这方面知识,文中肯定有错误之处,大家多指正。
文章的标题包含了本文的四方面主要内容:(1)Windows:本文是在windows环境下的汇编程序设计,调试环境为Windows Vista64位版,调用的均为windows API。
(2)X64:本文讨论的是x64汇编,这里的x64表示AMD64和Intel的EM64T,而不包括IA64。
至于三者间的区别,可自行搜索。
(3)汇编:顾名思义,本文讨论的编程语言是汇编,其它高级语言的64位编程均不属于讨论范畴。
(4)入门:既是入门,便不会很全。
其一,文中有很多知识仅仅点到为止,更深入的学习留待日后努力。
其二,便于类似我这样刚接触x64汇编的新手入门。
本文所有代码的调试环境:Windows Vista x64,Intel Core2Duo。
1.建立开发环境1.1编译器的选择对应于不同的x64汇编工具,开发环境也有所不同。
最普遍的要算微软的MASM,在x64环境中,相应的编译器已经更名为ml64.exe,随Visual Studio2005一起发布。
因此,如果你是微软的忠实fans,直接安装VS2005既可。
运行时,只需打开相应的64位命令行窗口(图1),便可以用ml64进行编译了。
第二个推荐的编译器是GoASM,共包含三个文件:GoASM编译器、GoLINK链接器和GoRC资源编译器,且自带了Include目录。
它的最大好外是小,不用为了学习64位汇编安装几个G的VS。
因此,本文的代码就在GoASM下编译。
第三个Yasm,因为不熟,所以不再赘述,感兴趣的朋友自行测试吧。
不同的编译器,语法会有一定差别,这在下面再说。
1.2IDE的选择搜遍了Internet也没有找到支持asm64的IDE,甚至连个Editor都没有。
PART 01 Visual Basic概述什么是程序设计语言?我们想用计算机解决一个问题,必须事先设计好计算机处理问题的步骤,然后把这些步骤按照计算机能够识别的指令编写出来。
并送给计算机执行,计算机才能按照我们的意图完成指定的工作。
我们把计算机能够执行的指令序列称为程序。
编写程序的过程称为程序设计。
显然我们人类是通过程序来告诉计算机该如何处理问题,那么如何与计算机进行交流?人类与计算机的交流存在鸿沟,计算机听不懂人类语言。
假如我们直接对着电脑说出汉语、英语、俄语等其他自然语言跟计算机交流,计算机听不懂。
计算机只能理解0和1的二进制的指令码,这个时候就需要一种填补语言(中间的媒介)来跨越人与计算机交流的鸿沟。
你好语言程序桥梁这种语言不仅我们人类能理解,,而且计算机也能明白,这种特殊的语言成为程序设计语言,实现人与计算机之间的交流。
程序设计语言与现代计算机共同诞生,共同发展,至今已有60多年的历史;形成规模庞大的家族,经历了机器语言、汇编语言和高级语言三个阶段。
计算机语言用二进制代码0和1来表示计算机可直接执行的指令,每条指令让计算机执行一个简单动作。
对人类来说机器语言比较晦涩难懂,但计算机却可以直接理解和执行,为了克服这个问题,在指令中使用助记符,这样形成了汇编语言。
汇编语言以约定的助记符来表示机器指令,每条汇编指令基本上与一条机器指令相对应,与机器语言比较,汇编语言比较直观,用汇编语言编写的程序经过简单的翻译,就可以被机器执行。
高级语言的语法规则简单清晰,是由英语单词和数学符号组成,最接近我们人类语言,比较容易掌握和理解。
但高级语言编写的程序,需要经过翻译软件翻译成机器指令后,才能被计算机执行。
现在比较流行的高级语言有:Visual Basic、C语言、Java语言。
Visual Basic是一种面向对象的可视化程序设计,它是在 Basic语言基础上发展起来的、功能强大的Windows应用程序的开发工具。
第1章汇编语言基础知识汇编语言是直接在硬件之上工作的编程语言,首先要了解硬件系统的结构,才能有效地应用汇编语言对其编程,因此,本章对硬件系统结构的问题进行部分探讨,首先介绍了计算机的基本结构、Intel公司微处理器的发展、计算机的语言以及汇编语言的特点,在此基础上重点介绍寄存器、内存组织等汇编语言所涉及到的基本知识。
1.1微型计算机概述微型计算机由中央处理器(Central Processing Unit,CPU)、存储器、输入输出接口电路和总线构成。
CPU如同微型计算机的心脏,它的性能决定了整个微型计算机的各项关键指标。
存储器包括随机存储器(Random Access Memory,RAM)和只读存储器(Read Only Memory,ROM)。
输入输出接口电路用来连接外部设备和微型计算机。
总线为CPU和其他部件之间提供数据、地址和控制信息的传输通道。
如图1.1所示为微型计算机的基本结构。
图1.1微型计算机基本结构特别要提到的是微型计算机的总线结构,它使系统中各功能部件之间的相互关系变为各个部件面向总线的单一关系。
一个部件只要符合总线结构标准,就可以连接到采用这种总线结构的系统中,使系统功能得到扩展。
数据总线用来在CPU与内存或其他部件之间进行数据传送。
它是双向的,数据总线的位宽决定了CPU和外界的数据传送速度,8位数据总线一次可传送一个8位二进制数据(即一个字节),16位数据总线一次可传送两个字节。
在微型计算机中,数据的含义是广义的,数据总线上传送的不一定是真正的数据,而可能是指令代码、状态量或控制量。
汇编语言程序设计2地址总线专门用来传送地址信息,它是单向的,地址总线的位数决定了CPU可以直接寻址的内存范围。
如CPU的地址总线的宽度为N,则CPU最多可以寻找2N个内存单元。
控制总线用来传输控制信号,其中包括CPU送往存储器和输入输出接口电路的控制信号,如读信号、写信号和中断响应信号等;也包括其他部件送到CPU的信号,如时钟信号、中断请求信号和准备就绪信号等。
windows环境下32位汇编语言程序设计附书代码汇编语言是一种底层计算机语言,用于编写与计算机硬件直接交互的程序。
在Windows环境下,可以使用32位汇编语言进行程序设计。
本文将介绍一些常见的32位汇编语言程序,并附带相关的代码示例。
1.程序的基本结构:在32位汇编语言中,程序的基本结构由三个部分组成:数据段、代码段和堆栈段。
数据段用来声明和初始化程序中使用的全局变量和常量。
例如,下面的代码段声明了一个全局变量message,存储了一个字符串。
```data segmentmessage db 'Hello, World!',0data ends```代码段包含了程序的实际执行代码。
下面的代码段使用`mov`指令将message变量中的字符串存储到寄存器eax中,并使用`int 21h`来调用MS-DOS功能1来显示字符串。
```code segmentstart:mov eax, offset messagemov ah, 09hint 21hmov ah, 4chint 21hcode ends```堆栈段用来存储函数调用过程中的局部变量和返回地址。
2.入栈和出栈操作:在程序中,我们经常需要使用堆栈来保存和恢复寄存器的值,以及传递函数参数和保存函数返回值。
以下是一些常用的堆栈操作指令: ```push reg ;将reg中的值压入堆栈pop reg ;将堆栈顶部的值弹出到reg中```下面的示例演示了如何使用堆栈来保存和恢复寄存器的值:```code segmentstart:push eax ;将eax保存到堆栈mov eax, 10 ;设置eax的值为10pop ebx ;将堆栈顶部的值弹出到ebxadd eax, ebx ;将eax和ebx相加int 3 ;调试中断,用于程序的暂停mov ah, 4chint 21hcode ends```3.条件判断和跳转指令:汇编语言中的条件判断和跳转指令用于根据条件的成立与否来改变程序的执行流程。
知识点第一章基础知识(1)正负数的补码表示, 掌握计算机中数和字符的表示;eg.假设机器字长为8位,[+3]补=00000011B,[-3]补= 11111101 H 。
十六进制数0FFF8H表示的十进制正数为65528D,表示的十进制负数为-8D。
8位二进制数被看成是带符号补码整数时,其最小值是-128,最大值是 127 。
第二章80x86计算机组织(1)中央处理机CPU的组成和80x86寄存器组,重点:专用寄存器,段寄存器eg: IP寄存器中保存的是?代码段中的偏移地址FLAGS标志寄存器中共有几位条件状态位6位,有几位控制状态位2位,标志寄存器分为哪2类?陷阱标志,中断标志。
(2)存储单元的地址和内容每一个字节单元给以一个唯一的存储器地址,称为物理地址;一个存储单元中存放的信息称为该存储单元的内容。
存储器地址的分段,(低位字节存放)低地址,(高位字节存放)高地址;实模式下逻辑地址、选择器和偏移地址;物理地址的表示段基地址加上偏移地址。
eg.如果SS=6000H,说明堆栈段起始物理地址是_____60000H___。
已知字节(00018H)=14H,字节(00017H)=20H,则字(00017H)为__1420H______。
如果(SI)=0088H,(DS)=5570H,对于物理地址为55788H的内存字单元,其内容为0235H,对于物理地址为5578AH的内存字单元,其内容为0E60H,那么执行指令LDS SI,[SI]以后,(SI)= 0235H ,(DS)= 0E60H .第三章80x86的指令系统和寻址方式与数据有关的寻址方式(立即寻址方式,寄存器寻址方式,直接寻址方式,寄存器间接寻址方式,寄存器相对寻址方式,基址变址寻址方式,相对基址变址寻址方式)和与转移地址有关的寻址方式(段内直接寻址,段内间接寻址,段间直接寻址,段间间接寻址)。
数据传送指令(通用数据传送指令、累加器专用传送指令、输入输出指令)、算术指令(加法指令、减法指令(*加减指令对4个标志位的影响[of,cf,sf,zf])、乘法指令(*乘法指令的要求:目的操作数必须是累加器)、除法指令(*被除数在累加器中,除法指令执行完以后,商和余数在?))、逻辑指令(逻辑运算指令(*XOR,AND,OR,TEST指令及指令执行后对标志位的影响)、移位指令)、串处理指令(与REP相配合工作的MOVS、STOS、LODS 指令,与REPE/REPZ和REPNE/REPNZ联合工作的CMPS、SCAS指令)、控制转移指令(无条件转移指令、条件转移指令、循环指令、子程序调用指令、中断)。
汇编语言程序设计的实验环境及上机步骤一、实验环境汇编语言程序设计的实验环境如下:1.硬件环境微型计算机(Intel x86系列CPU)一台2.软件环境⏹Windows98/2000/XP操作系统⏹任意一种文本编辑器(EDIT、NOTEPAD(记事本)、UltraEDIT等)⏹汇编程序(MASM.EXE或TASM.EXE)⏹连接程序(LINK.EXE或TLINK.EXE)⏹调试程序(DEBUG.EXE或TD.EXE)文本编辑器建议使用EDIT或NOTEPAD,汇编程序建议使用MASM.EXE,连接程序建议使用LINK.EXE,调试程序建议使用TD.EXE。
二、上机实验步骤注:以下步骤适用于除汇编语言程序设计的实验一到实验四外的所有实验(实验一到实验四仅使用TD.EXE)。
1.确定源程序的存放目录建议源程序存放的目录名为ASM(或MASM),并放在C盘或D盘的根目录下。
如果没有创建过此目录,请用如下方法创建:通过Windows的资源管理器找到C盘的根目录,在C盘的根目录窗口中点击右键,在弹出的菜单中选择“新建”→“文件夹”,并把新建的文件夹命名为ASM。
请把MASM.EXE、LINK.EXE、DENUG.EXE和TD.EXE都拷贝到此目录中。
2.建立ASM源程序建立ASM源程序可以使用EDIT或NOTEPAD(记事本)文本编辑器。
下面的例子说明了用EDIT文本编辑器来建立ASM源程序的步骤(假定要建立的源程序名为HELLO.ASM),用NOTEPAD(记事本)建立ASM源程序的步骤与此类似。
在Windows中点击桌面左下角的“开始”按钮→选择“运行”→在弹出的窗口中输入“ C:\ASM\HELLO.ASM”,屏幕上出现EDIT的编辑窗口,如图1所示。
图1 文本编辑器EDIT的编辑窗口窗口标题行显示了EDIT程序的完整路径名。
紧接着标题行下面的是菜单行,窗口最下面一行是提示行。
菜单可以用Alt键激活,然后用方向键选择菜单项,也可以直接用Alt-F打开File文件菜单,用Alt-E打开Edit编辑菜单,等等。
WindowsX8664位汇编语言入门Windows x86-64位汇编语言入门汇编语言是计算机硬件和操作系统之间的桥梁,它能够直接控制计算机的底层硬件。
对于计算机科学的学习者来说,了解汇编语言是非常重要的一步。
本文将介绍如何入门并学习Windows x86-64位汇编语言。
一、了解汇编语言的基本概念在开始学习汇编语言之前,我们需要先了解一些基本概念。
汇编语言是一种低级语言,它使用助记符来代替机器指令,这样更方便我们理解和编写程序。
汇编语言的基本单位是指令,每条指令对应着一条机器指令。
在x86-64架构中,指令长度可以是1到15个字节。
二、安装并配置开发环境要开始编写和执行汇编语言程序,我们首先需要安装一个好的开发环境。
在Windows操作系统上,常用的开发环境有MASM、NASM、TASM等。
这些开发工具可以帮助我们将汇编代码转换为可执行文件。
三、学习汇编语言的语法和指令集汇编语言与其他高级编程语言相比,语法更加简单和直接。
学习汇编语言的关键就是理解和掌握其语法和指令集。
在学习过程中,我们可以参考官方文档或者一些经典的教程,如《汇编语言程序设计》。
四、编写你的第一个汇编程序现在,我们可以尝试编写自己的第一个汇编程序。
我们可以从一个简单的程序开始,比如输出一个简单的“Hello, World!”。
下面是示例代码:section .datamsg db 'Hello, World!', 0section .textglobal _start_start:; 输出字符串mov eax, 4mov ebx, 1mov ecx, msgmov edx, 13int 0x80; 退出程序mov eax, 1xor ebx, ebxint 0x80这个程序使用Linux系统调用来输出字符串,并退出程序。
我们可以使用汇编器将其编译成可执行文件,然后在命令行中运行。
五、深入学习汇编语言的高级特性一旦掌握了汇编语言的基础知识,我们就可以进一步学习一些高级特性,如函数调用、内存管理、寄存器的使用等。
汇编语言程序设计教程(第二版)习题参考答案第1章计算机基础知识1.计算机的应用分哪几个方面,请举例说明书中未提到的领域的计算机应用。
科学计算、数据处理、计算机控制、计算机辅助设计、人工智能、企业管理、家用电器、网络应用。
书中未提及的如:远程教育、住宅小区控制、飞行系统控制与管理等。
2.简述计算机的发展过程,请查阅相关资料,列出微机的发展过程。
电子管、晶体管、集成电路、大规模集成电路以IBM为例,微机的发展:4004、8008、8080、8086/8088、80286、80386、80486、Pentium 系列3.计算机的字长是怎么定义的,试举例说明。
计算机能同时处理二进制信息的位宽定义为计算机的字长。
如8086能同时进行16位二进制数据的运算、存储和传输等操作,该机器的字长为16位。
4.汇编语言中的基本数据类型有哪些?数值型数据和非数值型数据。
非数值数据如字符、字符串、逻辑值等。
(1)7BCH=011110111100B=1980D(2)562Q=101110010B=370D(3)90D=01011010B=5AH(4)1110100.111B=164.7Q=74.EH30H~39H 41H~5AH 61H~7AH9.在汇编语言中,如何表示二进制、八进制、十进制和十六进制的数值?用相应进制的数值加上进制标记即可。
二进制用B,如10101010B八进制用Q,如437Q。
十进制用D或不用,如54D,或54。
十六进制用H,如27A8H10.完成下列二进制数的加减运算。
(1)10101010 + 11110000 (2)11001100 + 01010100=110011010 =100100000(3)11011010 - 01010010 (4)11101110 - 01001101=10001000 =1010000111.完成下列十六进制数的加减运算。
(1)0FEA9 - 8888=7621H (2)0FFFF - 1234=EDCBH(3)0EAC0 + 0028=EAE8H (4)3ABC + 1678=5134H12.完成下列BCD码的运算。
第1章汇编语言基础知识〔习题1.1〕简述计算机系统的硬件组成及各部分作用。
〔解答〕CPU:包括运算器、控制器和寄存器组。
运算器执行所有的算术和逻辑运算;控制器负责把指指令逐条从存储器中取出,经译码分析后向机器发出各种控制命令,并正确完成程序所要求的功能;寄存器组为处理单元提供所需要的数据。
存储器:是计算机的记忆部件,它用来存放程序以及程序中所涉及的数据。
外部设备:实现人机交换和机间的通信。
〔习题1.2〕明确下列概念或符号:主存和辅存,RAM和ROM,存储器地址和I/O端口,KB、MB、GB和TB。
〔解答〕主存又称内存是主存储器的简称,主存储器存放当前正在执行的程序和使用的数据,CPU可以直接存取,它由半导体存储器芯片构成其成本高、容量小、但速度快。
辅存是辅助存储器的简称,辅存可用来长期保存大量程序和数据,CPU 需要通过I/O接口访问,它由磁盘或光盘构成,其成本低、容量大,但速度慢。
RAM是随机存取存储器的英语简写,由于CPU可以从RAM读信息,也可以向RAM写入信息,所以RAM也被称为读写存储器,RAM型半导体存储器可以按地址随机读写,但这类存储器在断电后不能保存信息;而ROM中的信息只能被读出,不能被修改,ROM型半导体通常只能被读出,但这类存储器断电后能保存信息。
存储器由大量存储单元组成。
为了区别每个单元,我们将它们编号,于是,每个存储单元就有了一个存储地址,I/O接口是由一组寄存器组成,为了区别它们,各个寄存器进行了编号,形成I/O地址,通常称做I/O端口。
KB是千字节、MB是兆字节、GB是吉字节和TB是太字节,它们都是表示存储器存储单元的单位。
〔习题1.3〕什么是汇编语言源程序、汇编程序、目标程序?〔解答〕用汇编语言书写的程序就称为汇编语言源程序;完成汇编工作的程序就是汇编程序;由汇编程序编译通过的程序就是目标程序。
〔习题1.4〕汇编语言与高级语言相比有什么优缺点?〔解答〕汇编语言与高级语言相比的优点:由于汇编语言本质就是机器语言,它可以直接地、有效地控制计算机硬件,因而容易产生运行速度快,指令序列短小的高效目标程序,可以直接控制计算机硬件部件,可以编写在“时间”和“空间”两方面最有效的程序。
汇编程序设计语言知识点汇编程序设计语言是一种低级别的程序设计语言,用于编写计算机的底层代码。
它与高级语言相比,更加接近机器的指令集架构,可以直接操作计算机的硬件和寄存器。
在本文中,将介绍汇编程序设计语言的一些重要知识点。
一、汇编语言基础知识1. 汇编语言的发展历程:从机器语言到汇编语言;2. 汇编语言的组成部分:指令、操作数和寄存器;3. 汇编语言的语法规则:标号、指令、操作数和注释的格式;4. 汇编程序的编写流程:编辑、汇编、链接和运行。
二、汇编语言的数据类型1. 二进制数和十六进制数的表示方法;2. 常用的数据类型:字节、字和双字;3. 数据的存储方式:大端字节序和小端字节序;4. 数据的表示范围和溢出问题。
三、汇编语言的指令集1. 数据传输指令:MOV、XCHG、PUSH和POP等;2. 算术运算指令:ADD、SUB、INC和DEC等;3. 逻辑运算指令:AND、OR、XOR和NOT等;4. 条件转移指令:JMP、JZ、JE和JG等;5. 循环控制指令:LOOP、LOOPZ和LOOPNZ等;6. 系统调用指令:INT、CALL和RET等。
四、汇编语言的控制结构1. 顺序结构:代码按顺序执行;2. 条件结构:根据条件选择执行路径;3. 循环结构:根据条件循环执行代码块;4. 无限循环:使用JMP指令实现无限循环。
五、汇编语言的调试和优化1. 调试工具:调试器、寄存器监视、内存监视和断点设置;2. 常见的调试问题和解决方法;3. 优化技巧:减少指令数量、减少内存访问和提前计算等。
六、汇编语言的应用领域1. 操作系统开发:汇编语言作为操作系统内核的编程语言;2. 嵌入式系统开发:汇编语言用于编写驱动程序和底层代码;3. 游戏开发和图形编程:汇编语言用于优化性能和实现特殊效果;4. 加密和反汇编:汇编语言用于加密算法和反编译程序。
结语本文介绍了汇编程序设计语言的基础知识、数据类型、指令集、控制结构、调试和优化等重要知识点,以及其在不同领域的应用。
第1章Windows汇编语言程序设计基础Windows汇编语言程序分为控制台编程和图形界面编程两种,控制台编程相对简单一些。
为了由浅入深,本书从控制台编程开始讲解。
读者总希望用最快的速度掌握书中的概貌,为此从一个最简单的程序开始。
一些汇编语言语法也结合程序进行讲解,有些指令和语法用注解的方法说明。
1.1 第一个完整的Windows汇编语言程序Windows汇编语言程序有自己的编程规范,它的编程规范比Visual C要简单得多,调试也很方便。
更重要的是系统把重要的东西都呈现给读者,使读者更能掌握其中的本质。
用一条一条的汇编语言指令很难写出大程序,Windows汇编语言程序也是调用系统提供的API来写程序。
因而,用Windows汇编语言同样可写出大程序。
以下是一个最简单的Windows程序。
;程序功能:显示一个信息框。
;ex1.asm(e:\masm\base) ;程序名;编译链接方法:;ml /c /coff ex1.asm;link /subsystem:console ex1.obj.386 ;指明指令集.model flat,stdcall ;程序工作模式,flat为Windows程序使用的模式(代码和数据;使用同一个4GB段),stdcall为API调用时右边的参数先入栈option casemap:none ;指明大小写敏感include windows.incinclude user32.incincludelib user32.libinclude kernel32.incincludelib kernel32.lib.data ;数据段szCaption db '抬头串',0szText db 'Hello!',0.code ;代码段start:invoke MessageBox, ;显示信息框NULL, ;父窗口句柄offset szText, ;正文串的地址offset szCaption, ;抬头串的地址MB_OK ;按钮NULL ;退出代码end start ;指明程序入口点程序运行结果见图1-1。
说明:程序调用了两个Windows提供的API。
invoke是汇编语图1-1言中的伪指令,该指令的使用方法见1.4节。
1.2 编译、链接和运行1.2.1 创建编译链接环境(1)安装MASM615调试工具。
(2)建立一个VAR.BAT文件,内容如下。
@echo offrem 请根据 Masm32 软件包的安装目录修改下面的 Masm32Dir 环境变量!set Masm32Dir=c:\Masm32set include=%Masm32Dir%\Include;c:\Program Files\Microsoft Visual Studio\VC98\Include;(本行应接在上行后) Program Files\Microsoft Visual Studio\VC98\MFC\Include;(本行应接在上行后) %include%(本行应接在上行后)set lib=%Masm32Dir%\lib;%lib%set w2k=%Masm32Dir%\Incluse\w2k;%Include\w2k%set path=%Masm32Dir%\Bin;%Masm32Dir%\Include;%Masm32Dir%\Include\w2k;%Masm32Dir%\lib;%Masm32Dir%;%PATH%(本行应接在上行后)set Masm32Dir=echo on编译链接程序前,需要切换到命令提示符方式,并运行该文件(设置好环境),然后方可进行编译链接。
1.2.2 编译链接和运行以下以编译链接ex1.asm为例:(1)编译。
ML /Zi /c /Fl /coff ex1.asmML 参数说明(注意参数大小写):/Zi ––加符号调试信息/c ––连接前的编译/Fl –– F1[file]产生列表文件/coff ––产生COFF格式目标文件编译的更多参数说明,可用命令ML /?查阅。
(2)链接。
LINK /SUBSYSTEM:console ex1.obj其中console指明是控制台编程,如果是Windows窗口编程,则将console改为Windows。
(3)运行。
在Windows下双击ex1.exe或在DOS命令提示符下键入ex1回车。
1.2.3 建立编译链接批命令文件可以把编译链接过程写成批命令文件,以减少键盘输入量。
例如:MLEXE.BATML /Zi /c /Fl /coff %1.asmLINK /subsystem:console %1.objdel %1.objdir %1.*如果要编译链接ex1.asm,则只需输入:MLEXE ex1 回车1.3 将Windows汇编语言程序反汇编后的程序原形将可执行程序用IDA反汇编工具反汇编后,程序的代码部分可直接使用,程序的其他部分稍作修改后,即可再编译链接成可执行程序。
具体修改部分见程序尾的说明。
;iex1.asm,本程序为ex1.exe反汇编后的程序。
;iex1.asm(e:\masm\base);编译链接方法:;ml /c /coff iex1.asm;link /subsystem:Windows iex1.obj.386.model flat,stdcalloption casemap:none.datainclude windows.incinclude user32.incincludelib user32.libinclude kernel32.incincludelib kernel32.libCaption db '抬头串',0Text db 'Hello!',0.codepublic startstart proc nearpush 0 ;uTypepush offset Caption ;"抬头串"push offset Text ;"Hello!"push 0 ;hWndcall MessageBoxApush 0 ;uExitCodecall ExitProcessstart endpend start说明:API调用时右边的参数先入栈。
用反汇编工具IAD反汇编后,保留代码段不变,将数据段中的数据搬入代码段,将其余部分删除,再加入包含文件和程序中的前4条指令,即可再编译链接成可执行程序。
将可执行文件反汇编成汇编语言程序,经过适当修改后,再编译链接成可执行文件,这是十分有意义的。
1.4 invoke伪指令的使用格式、变量及数据段data和data?的区别1.4.1 invoke伪指令的使用格式invoke 伪指令的使用格式为:invoke 函数名[,参数1][,参数2]...参数的个数不定,可以没有,也可以有多个。
如果invoke与某个函数的参数个数不匹配(少或多),则编译时报错。
如果参数个数少,则报错“error A2137:too few arguments to INVOKE”;如果参数个数多,则报错“error A2137:too many arguments to INVOKE”。
1.4.2 变量1.变量的命名规则变量由大写字母A,B,…,Z,小写字母a,b,…,z,数字0,1,2,…,9,下划线,符号@、$和?组成,且变量的第一个符号不能是数字。
变量的长度不能超过240个字符,不能使用指令名关键字,在同一个作用域内不能重名。
应该养成良好的命名习惯,如表1-1所示。
表1-1例如:hWin 表示窗口句柄lpArray 表示指向数组的指针szString 以0结尾的字符串stWndClass WNDCLASS结构bNumber 以字节定义的数dwNumber 以双字定义的数wNumber 以字定义的数2.全局变量全局变量的作用域为整个程序。
在 .data和 .data?段内定义的变量为全局变量。
全局变量的定义格式为:变量名类型初始值变量名类型重复数量 dup(初始值)例如:count dw 0array db 10 dup(0)3.局部变量局部变量的作用域为一个程序内。
局部变量的定义格式为:local 变量名1[重复数量][:类型],变量名2[重复数量][:类型]...局部变量要放在子程序的开始位置,并且没有初始值。
例如:.386.model flat, stdcalloption casemap :noneinclude windows.incinclude kernel32.incincludelib kernel32.lib.codeSubProc proc,x:byte,y:bytelocal a:byte ;定义局部变量local b:byte ;定义局部变量mov al,xmov a,almov al,ymov b,alretSubProc endpmain procinvoke SubProc,1,2 ;调用子程序(右边参数先入栈)invoke ExitProcess,0 ;退出进程main endpend main4.局部变量在栈中的位置将以上程序用IDA反汇编后的程序如下:sub_401000 proc nearvar_2 = byte ptr -2var_1 = byte ptr -1arg_0 = byte ptr 8arg_4 = byte ptr 0Chpush ebpmov ebp, espadd esp, 0FFFFFFFCh ;(-4)的补码=0FFFFFFFChmov al, [ebp+arg_0] ;x=1mov [ebp+var_1], almov al, [ebp+arg_4] ;y=2mov [ebp+var_2], alleaveretn 8 ;将入口参数(x,y)退栈sub_401000 endppublic startstart proc nearpush 2push 1call sub_401000push 0 call $+5jmp ds:ExitProcessstartendp说明:参数在栈中的位置见图1-2。
–2 –1 ebp=esp[ebp+4][ebp+8][ebp+0C]图1-2 栈区示意图1.4.3 数据段data 和data?的区别程序的一般结构为:.data定义变量并初始化(有初始值) .data?定义变量(变量的初始值为'?') .const 定义常量 .code定义在 .data ?段中的变量的初始值只能是'?'。
定义在 .data ?段中的变量不占用磁盘空间,即不增加 .exe 文件的大小。