汇编:x86汇编环境搭建与基础框架(32位)

32位汇编代码编写环境:Visual Studio(笔者用的版本为2017);先来说一下在Visual Studio 2017中编写汇编代码的准备操作:

①创建空项目

②设置项目属性:平台工具集设置为Visual Studio 2015(v140),因为一些库再2015版本后取消了;

③为该项目生成自定义依赖项;

勾选masm文件

④设置汇编代码入口点为main

⑤为了方便阅读代码,可以下载插件

此处我们下载Asm Dude插件,帮助我们更好地编写代码(该插件可以高亮汇编代码)

此时就可以在项目中添加汇编源文件,此时的源文件的后缀名为.asm;

添加完成后就可以开始编写代码了。

代码基本框架

①指定启用的指令集;

在汇编语言编程中,指令集是处理器所支持的一系列指令的集合。在MASM(Microsoft Macro Assembler)中,用于指定处理器的指令集有:

复制代码
①.8086
描述:启用Intel 8086处理器指令集。
特点:仅支持8086及其兼容处理器的指令。
​
②.186
描述:启用Intel 80186处理器指令集。
特点:支持8086的指令集以及80186的新指令。
​
③.286
描述:启用Intel 80286处理器指令集。
特点:支持实模式和保护模式,增加了新指令。
​
④.386
描述:启用Intel 80386处理器指令集。
特点:支持32位操作,增加了更多的寄存器和指令。
​
⑤.486
描述:启用Intel 80486处理器指令集。
特点:增加了一些新的指令和性能优化。
​
⑥.586
描述:启用Intel Pentium(80586)处理器指令集。
特点:支持更高级的指令和优化。
②指定程序使用的内存模型和调用约定

指定程序使用的内存模型和调用约定时可以使用.model 指令;

内存模型

在DOS下的16位汇编程序中,内存模型有不同的选择(如tiny, small, compact, medium, large, huge),但在32位或64位模式下,这通常设为 flat(扁平模型),这意味着整个程序和数据都在一个线性地址空间中。

调用约定

调用约定(Calling Conventions)定义了函数调用时参数的传递方式、返回值的处理方式以及栈的清理;不同的调用约定在参数传递顺序、寄存器使用、栈管理等方面有所不同。以下是几种常见的调用约定:

复制代码
①cdecl(C Declaration):主要用于C语言程序中;参数从右到左压入栈中,调用者(caller)负责清理栈。这意味着调用者在函数调用结束后要调整栈指针以清理传递的参数。
②stdcall:主要用于Windows API和一些其他情况下,调用约定规定被调用者(callee)负责清理栈。
③fastcall:通过寄存器传递函数参数,从而提高函数调用的效率,相比于将所有参数压入栈中,使用寄存器传递参数可以减少内存访问次数,从而提升性能。
④thiscall:主要用于C++类的成员函数调用;在thiscall调用约定下,this指针(即当前对象的指针)通过寄存器传递,而其他参数通常通过栈传递。
⑤vectorcall:主要用于优化处理器支持SIMD(Single Instruction, Multiple Data)指令集的情况下向量和浮点数参数的函数调用,这种调用约定旨在通过使用寄存器传递参数来提高性能,特别是在处理大量浮点数和向量数据时。
③可以设置其他可选参数

此处我们可以使用option指令设置汇编器的各种选项,如如代码是否区分大小写;若此时要设置代码不区分大小写则可以按照如下方法进行编写:

option casemap:none
最简单的x86汇编程序:

汇编代码设置了汇编器的一些选项,定义了程序的内存模型和函数的调用约定,并且包含了数据段和代码段的定义,以及一个简单的过程 main

.586
.model flat,stdcall
option casemap:none
​
.data   ;数据段
​
.code   ;代码段
main proc  ;入口点
    mov eax,64h
    mov ebx,65h
main endp
end 

.586:这个指令告诉汇编器使用 Intel 80386 处理器及其支持的指令集。.586指令启用了对这些指令的支持。

.model flat, stdcall:这是一个模型指令,用于定义程序的内存模型和函数的调用约定。

  • flat 是指定了程序使用的内存模型。在这里,flat 内存模型表示程序使用的是平坦内存模型,即所有的内存地址都是在一个统一的地址空间中。

  • stdcall 是一个调用约定标识符,指示函数的调用约定。在这种调用约定下,函数的参数从右到左依次入栈,调用者清理栈。

option casemap:none:这个选项指令设置了汇编器的一些选项;casemap:none 设置了符号不进行大小写转换,这意味着汇编器不会将符号强制转换为特定的大小写格式,符号将保持其原始的大小写形式。

.data:是一个伪操作符,用于标记数据段的开始;在数据段中,程序可以定义变量和常量。

.code:是一个伪操作符,用于标记代码段的开始;在代码段中,程序包含了执行的指令。

main proc:是定义一个过程(procedure)的开始;这个过程是程序的入口点。(上述准备工作中已经在项目属性中将main作为代码入口点)

main endp:main endp 表示过程 main 的结束。

mov eax,64hmov ebx,65h:这两条指令将立即数 64h65h 分别加载到寄存器 eaxebx 中。

end: 用于标记程序的结束。

点击本地Windows调试器运行该代码;

由于在程序中我们没有设置输出,则可以在Visual Studio的寄存器窗口查看代码运行情况;

根据寄存器中的情况可以看出代码正常运行:64h、65h分别被写入EAXEBX两个寄存器中。

相关推荐
Crossoads2 天前
【汇编语言】call 和 ret 指令(一) —— 探讨汇编中的ret和retf指令以及call指令及其多种转移方式
android·开发语言·javascript·汇编·人工智能·数据挖掘·c#
Crossoads3 天前
【汇编语言】转移指令的原理(三) —— 汇编跳转指南:jcxz、loop与位移的深度解读
android·汇编·人工智能·redis·单片机·深度学习·机器学习
zhuqiyua3 天前
深入解析Kernel32.dll与Msvcrt.dll
汇编·microsoft·windbg·二进制·dll
Crossoads5 天前
【汇编语言】数据处理的两个基本问题(三) —— 汇编语言的艺术:从div,dd,dup到结构化数据的访问
android·linux·运维·服务器·汇编·机器学习·数据挖掘
Crossoads5 天前
【汇编语言】数据处理的两个基本问题(二) —— 解密汇编语言:数据长度与寻址方式的综合应用
android·java·开发语言·javascript·汇编·数据挖掘·c#
Coding~5 天前
逆向攻防世界CTF系列38-xxxorrr
c语言·汇编·安全
Crossoads6 天前
【汇编语言】数据处理的两个基本问题 —— 汇编语言中的数据奥秘:数据位置与寻址方式总结
android·汇编·人工智能·redis·单片机·深度学习·机器学习
Crossoads7 天前
【汇编语言】更灵活的定位内存地址的方法(一)—— 字符操作:and与or指令、ASCII码及大小写转换
android·linux·运维·服务器·汇编·机器学习·数据挖掘
不会写算法的小沈7 天前
函数栈帧的创建与销毁
c语言·汇编·数据结构
zhuqiyua8 天前
windows二进制安全零基础(二)
汇编·安全·二进制