简述MASM宏汇编

2024-04-25 00:04
文章标签 简述 汇编 masm

本文主要是介绍简述MASM宏汇编,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Hello , 我是小恒不会java。今天写写x86相关底层的东西

在这里插入图片描述

寄存器

8086由BIU和EU组成
8088/8086寄存器有14个。8通用,4段,1指针,1标志
8个通用寄存器:这些寄存器可以用来存储任意类型的数据,包括整数、地址等。8086有8个通用寄存器,分别是:
AX(Accumulator):累加器,用于存储计算结果和中间结果。
BX(Base Register):基址寄存器,用于存储基址。
CX(Count Register):计数寄存器,用于存储循环次数和计数。
DX(Data Register):数据寄存器,用于存储乘法和除法操作的数据。
SI(Source Index):源索引寄存器,用于存储源操作数的地址。
DI(Destination Index):目标索引寄存器,用于存储目标操作数的地址。
BP(Base Pointer):基址指针寄存器,用于存储基址指针。
SP(Stack Pointer):堆栈指针寄存器,用于存储堆栈顶部的地址。
4个段寄存器:这些寄存器用于存储内存段的地址。8086有4个段寄存器,分别是:
CS(Code Segment):代码段寄存器,用于存储代码段的地址。
DS(Data Segment):数据段寄存器,用于存储数据段的地址。
SS(Stack Segment):堆栈段寄存器,用于存储堆栈段的地址。
ES(Extra Segment):附加段寄存器,用于存储附加段的地址。
1个指针寄存器:
IP(Instruction Pointer):指令指针寄存器,用于存储下一条指令的地址。
1个标志寄存器:
FLAGS:标志寄存器,用于存储指令执行过程中产生的状态信息,如进位、溢出、零等。

寄存器具体隐式用法我在此不多赘述

物理地址

物理地址 (PA) = (CS << 4) + IP

常见指令

数据传输指令:

mov:移动数据,从一个寄存器到另一个寄存器,或从内存到寄存器,反之亦然。
push:将数据压入栈。 pop:从栈中弹出数据。
xchg:交换两个寄存器或一个寄存器和内存位置的内容。
lea:加载有效地址,通常用于计算内存偏移。
算术和逻辑指令:

add:加法。
sub:减法。
mul:无符号乘法。
imul:有符号乘法。
div:无符号除法。
idiv:有符号除法。
inc:递增寄存器或内存位置的内容。
dec:递减寄存器或内存位置的内容。
neg:取负数。
and:按位与。
or:按位或。
xor:按位异或。
not:按位非。
shl/sal:左移。
shr/sar:右移(逻辑右移/算术右移)。
控制流指令:
jmp:无条件跳转。
call:调用子程序。
ret:从子程序返回。
je/jz:如果相等/为零则跳转。
jne/jnz:如果不等于/不为零则跳转。
jg/jnle:如果大于/不小于等于则跳转。
jge/jnl:如果大于等于/不小于则跳转。
jl/jnge:如果小于/不大于等于则跳转。
jle/jng:如果小于等于/不大于则跳转。
test:测试寄存器或内存位置的内容,常用于条件跳转。
字符串处理指令:
lods:从字符串中加载字节/字/双字。
stos:存储字节/字/双字到字符串。
cmps:比较字符串。 scas:扫描字符串。
输入/输出指令:
in:从端口读取数据。
out:向端口写入数据。 系统指令:
syscall:执行系统调用。
int:触发中断。
iret:从中断返回。

MOV 指令
mov 是“Move”的缩写,用于在汇编语言中执行数据传输操作,即从一个源(source)复制数据到一个目标(destination)。其基本语法是:

mov dst, src

其中:

  • dst 是目标操作数,可以是寄存器、内存位置(通过地址表达式指定)或其他可寻址的数据对象。
  • src 是源操作数,同样可以是寄存器、内存位置、立即数(常数值)等。

mov 指令的主要功能是将 src 中的值直接拷贝到 dst,实现数据的移动或赋值。例如:

mov eax, ebx       ; 将 ebx 寄存器的值复制到 eax 寄存器
mov [esp], 0x1234  ; 将立即数 0x1234 存储到 esp 指向的内存位置
mov eax, [0x1000]  ; 从内存地址 0x1000 处读取数据并存入 eax 寄存器

LEA 指令
lea 是“Load Effective Address”的缩写,它的功能不是直接传送数据,而是计算并获取源操作数所代表的内存地址,并将这个地址(而非地址处的数据)存放到目标寄存器中。其基本语法是:

lea dst, src

这里的 dst 仍然是目标寄存器,而 src 是一个地址表达式,通常由一个基址寄存器加上一个偏移量(可以是常数或寄存器)构成。lea 指令并不访问内存,它仅仅计算地址表达式的值并将其存入目标寄存器。

使用 lea 的典型场景包括:

  • 快速计算数组元素的地址,无需额外的算术运算。
  • 在不实际加载数据的情况下获取变量或数据结构成员的地址。
  • 作为某种形式的算术运算(如简单的加法或乘法)的替代,特别是在地址计算中。

例如:

lea eax, [ebx + 4*ecx]  ; 计算 ebx 加上 4 倍 ecx 的值所对应的地址,并将该地址存入 eax
lea edi, [ebp - 8]      ; 获取当前栈帧中偏移量为 -8 的局部变量的地址,存入 edi

mov 指令用于数据的直接复制,而 lea 指令则用于获取和存储内存地址

代码片段

基本结构
DATAS SEGMENT; 数据定义
DATAS ENDSCODES SEGMENTASSUME CS:CODES, DS:DATAS; 主程序和子程序
CODES ENDSEND START
常用结构

.MODEL SMALL; 定义堆栈段
.STACK; 数据段声明
.DATA; 代码段声明
.CODE; 程序入口点
.STARTUP; 结束程序执行
.EXIT; 定义子程序PRINT_STRING; 程序结束标记
END
定义程序模式:练习的话用小内存模式
.MODEL SMALL
; 使用`MODEL SMALL`定义程序模式,指定小模式内存模型,程序段(代码和数据)不超过64KB。
定义字符串类型数据
 STRING  DB  'Hello World!',13,10,'$';; 声明一个字符串变量STRING,内容为'Hello World!\r\n$'; 其中,'\r'代表回车(Carriage Return,ASCII码13),'\n'代表换行(Line Feed,ASCII码10); '$'字符作为字符串结束符,某些情况下用于标识字符串的结尾
创建子程序
NAME PROC; 子程序主体代码; ...; 子程序返回RETNAME ENDP
子程序调用
 CALL NAME
计算两个数的和:
MOV AX, NUM1
ADD AX, NUM2
MOV SUM, AX
比较两个数:
MOV AX, NUM1
CMP AX, NUM2
JG GREATER
JL LESS
JE EQUAL
输出字符串到屏幕:
LEA DX, STRING;STRING为变量名
MOV AH, 9
INT 21H
读取字符:
MOV AH, 1
INT 21H
输出字符:
MOV AH, 2
MOV DL, 'A'
INT 21H

打印字符串实例

; 使用`MODEL SMALL`定义程序模式,指定小模式内存模型,程序段(代码和数据)不超过64KB。.MODEL SMALL; 定义堆栈段
.STACK; 数据段声明
.DATA; 声明一个字符串变量STRING,内容为'Hello World!\r\n$'; 其中,'\r'代表回车(Carriage Return,ASCII码13),'\n'代表换行(Line Feed,ASCII码10); '$'字符作为字符串结束符,某些情况下用于标识字符串的结尾STRING  DB  'Hello World!',13,10,'$'; 代码段声明
.CODE; 程序入口点
.STARTUP; 调用子程序PRINT_STRING,输出字符串CALL PRINT_STRING; 结束程序执行
.EXIT; 定义子程序PRINT_STRING
PRINT_STRING PROC; LEA (Load Effective Address)指令将STRING变量的地址加载到DX寄存器LEA  DX, STRING; 将AH寄存器设置为9,这是DOS中断INT 21H的功能号,表示要执行"显示字符串"操作MOV  AH, 9; 调用DOS中断INT 21H,执行显示字符串功能。此时DX寄存器保存了待显示字符串的地址INT  21H; 子程序返回RET
PRINT_STRING ENDP; 程序结束标记
END

子程序创建实例

; 使用`MODEL SMALL`定义程序模式,指定小模式内存模型,程序段(代码和数据)不超过64KB。.MODEL SMALL; 定义堆栈段
.STACK; 数据段声明
.DATA; 声明一个字符串变量STRING,内容为'Hello World!\r\n$'; 其中,'\r'代表回车(Carriage Return,ASCII码13),'\n'代表换行(Line Feed,ASCII码10); '$'字符作为字符串结束符,某些情况下用于标识字符串的结尾STRING  DB  'Hello World!',13,10,'$'; 代码段声明
.CODE; 程序入口点
.STARTUP; 调用子程序PRINT_STRING,输出字符串CALL PRINT_STRING; 结束程序执行
.EXIT; 定义子程序PRINT_STRING
PRINT_STRING PROC; LEA (Load Effective Address)指令将STRING变量的地址加载到DX寄存器LEA  DX, STRING; 将AH寄存器设置为9,这是DOS中断INT 21H的功能号,表示要执行"显示字符串"操作MOV  AH, 9; 调用DOS中断INT 21H,执行显示字符串功能。此时DX寄存器保存了待显示字符串的地址INT  21H; 子程序返回RET
PRINT_STRING ENDP; 程序结束标记
END

AH实例

AH 寄存器是 8086 汇编语言中的一个 8 位寄存器,属于 16 位寄存器 AX 的高 8 位部分

在 DOS 操作系统中,通过调用中断 21H 可以执行各种功能。这些功能由 AH 寄存器的值确定。例如,AH 寄存器的值设置为 9 表示调用 DOS 的输出字符串功能,值设置为 4CH 表示调用 DOS 的退出功能。

以下是一个简单的汇编程序示例,演示了如何使用 AH 寄存器调用 DOS 的输出字符功能:

.MODEL SMALL
.STACK
.DATACHAR DB 'A'
.CODE
.STARTUPMOV AH,2 ; 设置 AH 寄存器的值为 2,表示调用 DOS 的输出字符功能MOV DL,CHAR ; 将 CHAR 变量的值加载到 DL 寄存器INT 21H ; 调用 DOS 中断
.EXITEND

在这个示例中,程序首先将 AH 寄存器的值设置为 2,表示调用 DOS 的输出字符功能。然后,将 CHAR 变量的值加载到 DL 寄存器,最后使用 INT 21H 指令调用 DOS 中断。这将在屏幕上输出字符 ‘A’。

求和案例

;完整段的求3+5的和
DATAS  SEGMENTFIVE  DB    5
DATAS  ENDSSTACKS  SEGMENTDB  128 DUP (?)
STACKS  ENDSCODES  SEGMENTASSUME    CS:CODES,DS:DATAS,SS:STACKS
START:MOV AX,DATASMOV DS,AXMOV AL,FIVEADD AL,3ADD AL,30HMOV DL,ALMOV AH,2INT 21HMOV AH,4CHINT 21HCODES  ENDSEND  START

调用宏库案例

INCLUDE  MACROOUT.LIB;调用库DATAS SEGMENTSTRING  DB 'Hello World',13,10,'$';定义字符串数据DATAS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATASSTART:MOV AX,DATASMOV DS,AXOUTPUT STRING;使用output库内方法;使用寄存器中断程序MOV AH,4CHINT 21HCODES ENDSEND START

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这篇关于简述MASM宏汇编的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/933202

相关文章

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

汇编:嵌入式软件架构学习资源

成为嵌入式软件架构设计师需要掌握多方面的知识,包括嵌入式系统、实时操作系统、硬件接口、软件设计模式等。 以下是一些推荐的博客和网站,可以帮助你深入学习嵌入式软件架构设计: ### 1. **Embedded.com**    - **网址**: [Embedded.com](https://www.embedded.com/)    - **简介**: 这是一个专注于嵌入式系统设计的专业网

1、简述linux操作系统启动流程

1、简述linux操作系统启动流程 启动第一步--加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它。这是因为BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、PnP特性等等。开机时将ROM中的指令映射到RAM的低地址空间,CPU读取到这些指令,硬件的健康状况进行检查,按照BIOS中设置的启

GDB 查看汇编

查看汇编 x disassemble

C语言-程序环境 #预处理 #编译 #汇编 #链接 #执行环境

文章目录 前言 一、程序的环境翻译和执行环境 二、翻译环境 (一)、整体把握 (一)、编译 1、预处理(预编译) 2、编译 a、词法分析 b、语法分析 c、语义分析 d、符号汇总 3、汇编 (二)、链接 三、运行环境 总结​​​​​​​ 前言 路漫漫其修远兮,吾将上下而求索; PS:本文参考了《程序员的自我修养》,致敬大佬们! 一、程序的

Linux 技巧汇编

10个重要的Linux ps命令实战 显示所有当前进程 根据用户过滤进程 通过cpu和内存使用来过滤进程 通过进程名和PID过滤 根据线程来过滤进程 树形显示进程 显示安全信息 格式化输出root用户(真实的或有效的UID)创建的进程 使用PS实时监控进程状态 https://linux.cn/article-4743-1.html Python 云服务器应用 | Http

正点原子阿尔法ARM开发板-IMX6ULL(二)——介绍情况以及汇编

文章目录 一、裸机开发(21个)二、嵌入式Linux驱动例程三、汇编3.1 处理器内部数据传输指令3.2 存储器访问指令3.3 压栈和出栈指令3.4 跳转指令3.5 算术运算指令3.6 逻辑运算指令 一、裸机开发(21个) 二、嵌入式Linux驱动例程 三、汇编 我们在进行嵌入式 Linux 开发的时候是绝对要掌握基本的 ARM 汇编,因为 Cortex-A 芯片一

【Java String】简述String类比较和常量池内存分析

一、引出正题 String 类型对象进行比较时,我们一般使用 equals() 的方式进行值比较,但是有时候可能会出现 == 对象比较的方式。 在使用 == 比较的时候,往往是和String在JVM内存存储结构有关,这也引起了部分同学使用时的错误,那么接下来我们来详细分析一下此问题。 二、举例说明 1、new String("xx")都是在堆上创建字符串对象。当调用 intern() 方

【微机】DOSBox在windows上的安装和masm的配置

本文首发于 ❄️慕雪的寒舍 最近学校学习微型计算机原理与接口技术,需要用到DOSBox来模拟DOS环境进行汇编编程的学习。 本文记录了如何在windows11/10上安装DOSBox0.74并配置masm5 1.安装 这两个软件我打包上传到了百度云盘。放心,加起来也就2mb,下载应该不会很久 链接: https://pan.baidu.com/s/1vjbSL7iwP8WpMVA9