简述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 ENDS

CODES SEGMENT
    ASSUME CS:CODES, DS:DATAS
    ; 主程序和子程序
CODES ENDS

END 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
    ; 子程序主体代码
    ; ...

    ; 子程序返回
    RET

NAME 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
.DATA
    CHAR DB 'A'
.CODE
.STARTUP
    MOV AH,2 ; 设置 AH 寄存器的值为 2,表示调用 DOS 的输出字符功能
    MOV DL,CHAR ; 将 CHAR 变量的值加载到 DL 寄存器
    
    
    INT 21H ; 调用 DOS 中断
.EXIT
    END

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

求和案例

;完整段的求3+5的和
DATAS  SEGMENT
    FIVE  DB    5
DATAS  ENDS

STACKS  SEGMENT
      DB  128 DUP (?)
STACKS  ENDS

CODES  SEGMENT


     ASSUME    CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    MOV AL,FIVE
    ADD AL,3
    ADD AL,30H
    MOV DL,AL
    
    MOV AH,2
    INT 21H
    
    MOV AH,4CH
    INT 21H
    
CODES  ENDS

    END  START

调用宏库案例



INCLUDE  MACROOUT.LIB;调用库

DATAS SEGMENT

    STRING  DB 'Hello World',13,10,'$';定义字符串数据

DATAS ENDS

CODES SEGMENT

    ASSUME CS:CODES,DS:DATAS

START:

    MOV AX,DATAS

    MOV DS,AX

    OUTPUT STRING;使用output库内方法

 
;使用寄存器中断程序
  MOV AH,4CH

    INT 21H

CODES ENDS

    END START


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/570976.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Modbus转Profinet网关接电表与工控机通讯

Modbus转Profinet网关&#xff08;XD-MDPN100/300&#xff09;的主要功能是实现Modbus协议和Profinet协议之间的转换和通信。Modbus转Profinet网关集成了Modbus和Profinet两种协议&#xff0c;支持Modbus RTU主站/从站&#xff0c;并可以与RS485接口的设备&#xff0c;如变频器…

找对方法,单位信息宣传工作向媒体投稿其实也简单

曾经,作为一名肩负单位信息宣传重任的我,每当面对那堆叠如山的稿件与闪烁不定的电脑屏幕,心中总会涌起一股无尽的焦虑与疲惫。尤其在向媒体投稿这个环节,我仿佛陷入了一个难以挣脱的漩涡,邮箱投稿的艰辛、审核的严苛、出稿的迟缓以及成功发表的少之又少,如同一座座无形的大山压…

力扣面试 150二叉搜索树迭代器 中序遍历 栈模拟递归 步骤拆分

Problem: 173. 二叉搜索树迭代器 思路 &#x1f469;‍&#x1f3eb; 三叶 复杂度 时间复杂度: O ( 1 ) O(1) O(1) 空间复杂度: O ( h ) O(h) O(h) Code class BSTIterator { Stack<TreeNode> d new Stack<>();public BSTIterator(TreeNode root){dfsLe…

书生·浦语大模型第二期实战营第七节-OpenCompass 大模型评测实战 笔记和作业

来源&#xff1a; 视频教程&#xff1a;https://www.bilibili.com/video/BV1Pm41127jU/?spm_id_from333.788&vd_sourcef4a51f7f5a63e756f73ad0dff318c1a3 文字教程&#xff1a;https://github.com/InternLM/Tutorial/blob/camp2/opencompass/readme.md 作业来源&#x…

day12 过一遍Nestjs框架(java转ts全栈/3R教室)

介绍&#xff1a;NestJS是Ts技术栈的后端框架&#xff0c;相当于Java中的springboot。 学习方法&#xff1a;与java技术体系进行对比学习。学习目标&#xff1a;nest相关知识也是挺多&#xff0c;但对比学spring的时候&#xff0c;大部分在项目生产中都是套路化的&#xff0c;大…

SpringMVC基础篇(二)

文章目录 1.Postman1.基本介绍Postman是什么&#xff1f; 2.Postman快速入门1.Postman下载点击安装自动安装在系统盘 2.基本操作1.修改字体大小2.ctrl “” 放大页面3.进入创建请求界面 2.需求分析3.具体操作4.保存请求到文件夹中1.点击保存2.创建新的文件夹3.保存成功 3.使用…

Linux系统IO

Linux系统中的IO函数主要包括两大类&#xff1a;标准C库中的函数和Linux系统调用。这些函数可以用于文件操作、网络通信、设备控制等多种IO任务。以下是Linux系统中常用的IO函数和系统调用的概述&#xff1a; 标准C库IO函数 这些函数是高级的、封装好的&#xff0c;并且与操作…

一些好听且有心意的英文全名Burwood新南威尔士州伯伍德喝酒上脸就是乙醛中毒1. 康奈尔大学官宣恢复标化要求2. 香港城市大学(东莞)正式设立!

目录 一些好听且有心意的英文全名 Burwood新南威尔士州伯伍德 喝酒上脸就是乙醛中毒 1. 康奈尔大学官宣恢复标化要求 2. 香港城市大学&#xff08;东莞&#xff09;正式设立&#xff01; 一些好听且有心意的英文全名 在选择好听且有意义的英文全名时&#xff0c;我们可…

[MoeCTF-2022]Sqlmap_boy

title:[MoeCTF 2022]Sqlmap_boy 查看网页源代码&#xff0c;得到提示 <!-- $sql select username,password from users where username".$username." && password".$password.";; --> 用万能密码绕过&#xff0c;用’"闭合 爆数据库…

【NLP】大语言模型基础之GPT

大语言模型基础之GPT GPT简介1. 无监督预训练2. 有监督下游任务微调 GPT-4体系结构1. GPT-4的模型结构2. GPT-4并行策略3. GPT-4中的专家并行GPT-4的特点 参考连接 以ELMo为代表的动态词向量模型开启了语言模型预训练的大门&#xff0c;此后&#xff0c;出现了以GPT和BERT为代表…

Simulink从0搭建模型03-Enabled Subsystem 使能子系统

参考博客 b站视频 【Simulink 0基础入门教程 P4 使能子系统 Enabled Subsystem 的使用介绍】 个人听了这个博主的视频风格觉得很适合我入门学习&#xff0c;讲得很清楚。 另外&#xff0c;视频里面教得很详细了&#xff0c;我也不会再详细写怎么打开创建等步骤&#xff0c;跟着…

年如何在不丢失数据的情况下解锁锁定的 Android 手机?

当您忘记密码、PIN 码或图案并且想要解锁 Android 手机时&#xff0c;您可能会丢失 Android 手机上的数据。但您无需再担心&#xff0c;因为在这里&#xff0c;我们想出了几种解锁锁定的 Android 手机而不丢失数据的方法。 方法 1. 使用 Android Unlock 解锁锁定的 Android 且不…

拿捏 顺序表(1)

目录 1. 顺序表的分类2. 顺序表实现3. 顺序表实现完整代码4. 总结 前言: 一天xxx想存储一组数据, 并且能够轻松的实现删除和增加, 此时数组大胆站出, 但是每次都需要遍历一遍数组, 来确定已经存储的元素个数, 太麻烦了, 于是迎来了顺序表不屑的调侃: 数组你不行啊… 顺序表是一…

MSE实现全链路灰度实践

技术架构包括以下基础设施和云服务&#xff1a; 1个地域&#xff1a;ACK集群、微服务应用、MSE实例均部署在同一地域下。 1个专有网络VPC&#xff1a;形成云上私有网络&#xff0c;确保核心云资源的网络环境&#xff0c;如容器服务ACK、微服务引擎MSE。 ACK集群&#xff1a;简单…

升级 jQuery:努力打造健康的 Web 生态

jQuery 对 Web 的影响始终是显而易见的。当 jQuery 在 2006 年首次推出时&#xff0c;几乎立即成为 Web 开发人员的基本工具。它简化了 JavaScript 编程&#xff0c;使操作 HTML 文档、处理事件、执行动画等变得更加容易。从那时起&#xff0c;它在 Web 标准和浏览器功能的演变…

idea中打印日志不会乱码,但是部署到外部tomcat中乱码了。

问题&#xff1a;如图Tomcat乱码&#xff0c;而且启动时的系统日志不会乱码&#xff0c;webapp中的打印日志才乱码。 idea中的情况如下&#xff1a;正常中文展示。 问题分析&#xff1a;网上分析的原因是Tomcat配置的字符集和web应用的字符集不匹配&#xff0c;网上集中的解决…

Springboot的日常操作技巧

文章目录 1、自定义横幅2、容器刷新后触发方法自定义3、容器启动后触发方法自定义**CommandLineRunner**ApplicationRunner 不定时增加 参考文章 1、自定义横幅 简单就一点你需要把banner.text放到classpath 路径下 &#xff0c;默认它会找叫做banner的文件&#xff0c;各种格式…

“奇观”初见,祁门竞赛上海正式发

布给上下山水、左右人文的“徽州”&#xff0c;另起一笔“烟火” 城市更新从空间营造进入地方创生。何为地方&#xff1f;如何创生&#xff1f;其关键也许在于“持续打开”&#xff0c;源源不断吸引新生力量参与&#xff0c;从在地文化中生长出创作生态。 镶嵌于长三角腹地&a…

Ubuntu Pycharm安装

下载PyCharm&#xff0c;https://www.jetbrains.com/pycharm/download/?sectionlinux 然后按照下图执行安装&#xff1a; 安装的时候可能出现的问题&#xff1a; 问题1&#xff1a;No JDK found. Please validate either PYCHARM_JDK, JDK_HOME or JAVA_HOME environment var…

SHELL脚本(全是干货)

一、shell是什么&#xff1f; 1. 1 shell 是一种脚本语言 脚本语言的本质是一个文件&#xff0c;文件里面存放的是特点格式的指令&#xff0c;系统可以使用脚本解析器翻译或者解析指令&#xff0c;并且执行&#xff08;它不需要编译&#xff09; shell 即是应用程序&#xff…
最新文章