汇编: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两个寄存器中。

相关推荐
百年孤独_3 天前
对于基础汇编的趣味认识
汇编·性能优化
xiaozhiwise4 天前
ARM base instruction -- ccmp
汇编
向你扔鸡爪6 天前
Visual Studio-X64汇编编写
汇编·windows·visual studio
Lordaeron_ESZ6 天前
CSAPP Attack Lab
linux·汇编
xiaozhiwise7 天前
ARM base instruction -- sxtw
汇编
天赐细莲11 天前
C++的哲学思想
java·c语言·汇编·c++·python
王鑫的博客88611 天前
ARM基础知识点及简单汇编语法
linux·汇编·arm开发
洛书千年11 天前
linux驱动开发-arm汇编基础
汇编·arm开发·驱动开发
小咖拉眯11 天前
vscode将c++项目打包exe进行反汇编练习
c语言·汇编·c++·ide·vscode·安全·密码学
妖怪喜欢风13 天前
Linux 5.0在start_kernel之前做了什么事?(以aarch64为例)
linux·汇编