汇编语言(详解)

embedded/2024/9/24 16:04:50/

汇编语言安装指南

第一步:在github上下载汇编语言的安装包

网址:GitHub - HaiPenglai/bilibili_assembly: B站-汇编语言-pdf、代码、环境等资料B站-汇编语言-pdf、代码、环境等资料. Contribute to HaiPenglai/bilibili_assembly development by creating an account on GitHub.icon-default.png?t=N7T8https://github.com/HaiPenglai/bilibili_assembly

第二步:解压汇编语言的安装包

然后回到解压问价夹------> 复制MASM文件

当然这个时候窗口有点小需要我们手动修改一些文件做处理

右击鼠标,找到文件的起始位置,复制文件起始位置的路径,不要复制到引号

复制起始位置到电脑的文件搜索栏中搜索【搜索出如下的页面显示】

修改文件窗口的大小

双击打开文件后文件显示出如下的的文本【修改文本中相关参数改变汇编模拟器的窗口大小】

修改output参数,将output的参数改为ddraw

参数修改完毕后继续打开汇编模拟器,会发小窗口的大小发生改变

【mount c f:\masm 含义是将c挂载到f盘的masm】

【c: 表示进入编译环境】

【dir 表示查看当前环境下有哪些文件】

下一步:写入debug,是一个编译所用的环境汇编语言的编程是在debug上面进行的


汇编:mov,add,sub 指令

进入汇编指令控制面板

#if 0mount c f:\masmc:dirdebugr#endif

进入debug模式使用 r 命令查看寄存器

a 指令可以在汇编中编写需要的东西

【把要写的东西写入cs:ip地址中,cs:ip,cs 表示的是代码段的地址 + ip表示的是偏移组成20位物理地址】

汇编指令的含义

  • mov 寄存器, 数据 如:mov ax ,8
  • mov 寄存器 , 寄存器 如: mov ax ,bx
  • mov 寄存器 , 内存单元 如:mov ax ,[0]
  • mov 内存单元,寄存器 如:mov [0],ax
  • mov 段寄存器,寄存器 如:mov ds,ax

使用T指令执行刚刚编写的指令

【mov ax 8 指令的作用:将8移动到ax中】

【mov bx ax 相当于把后面寄存器的值移动到前面的寄存器中】

【mov ch,10】

继续使用命令编写汇编指令

【mov ah ,13】 -----------------> 把8移动到ah的低8位中

【mov bl, 23】 -----------------> 把23移动到bl的高8位中

【mov ch ,al】 -----------------> 把al移动到ch的高8位中

Add指令

【add ax,3】-----------------------> 把3的值加给了ax

【add bx,4】-----------------------> 把4的值加给了bx

【add,cx,bx】-----------------------> 把bx的值加给了cx

数值太大的话会发生越界现象【这个时候会发生进位现象,汇编语言越界会将越界的值舍弃掉】

汇编语言当中超过了特定的界限【多出来的一位会被舍弃掉:高位和地位都是这种情况】

汇编语言基础Sub指令】

sub 内存单元,寄存器 比如:sub【0】,ax

字母表示的数字含义

A == 10 , B == 11, C == 12,D == 13, E == 14,F == 15,G == 16

汇编寄存器简称

【AX : 累加寄存器】

【BX : 基址寄存器】

【CX : 计数寄存器】

【DX: 数据寄存器】

【SP : 堆栈指针寄存器】

【BP:基址指针寄存器】

【SI:源变址寄存器】

【DI:目的变址寄存器】

【IP:指令指针寄存器】

【CS:代码段寄存器】

【DS:数据段寄存器】

【SS:堆栈段寄存器】

【ES:附加段寄存器】

【OF:溢出标志操作数超出机器能表示的范围,表示溢出,溢出时为1】

【SF:符号标志,记录运算结果的符号,结果负时为1】

【ZF:零标志,运算结果0时为1,否则为0】

【CF:进位标志,最高有效位产生进位时为1,否则为0】

【AF:辅进位标志,运算时,第三位向第四位产生进位时为1,否则为0】

【PF:奇偶标志,运算结果操作数为1的个数为偶数个时为1,否则为0】

【DF:方向标志,用于串处理,DF=1时,每次操作后使SI和DI减小,DF= 0时则增大】

【IF:中断标志 IF = 1 时,允许向CPU响应屏蔽中断,否则关闭中断】

【TF:陷阱标志,用于调试单步操作】

汇编指令:mul,div,and,or

[汇编指令    mul]

  • 1:两个数相乘:两个数相乘,要么都是8位,要么都是16位,如果是8位,一个默认放在AL中,另外一个放在8为reg或内存字节单元中,如果是16位,一个默认在AX中,另外一个放在16位的reg或内存字节单元中。
  • 2:结果--->如果是8位乘法,结果默认放在AX中:如果是16位乘法结果高位默认在DX中,低位放在AX中

【汇编指令DIV】

  • 1:除数-------> 使用div做除法的时候应该注意以下问题
  • (除数有8位和16位两种在,在一个reg的内存单元中)
  • 2:被除数:默认放在AX或DX和AX中,如果除数为8为,被除数则为16位,默认在AX中存放,如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位。
  • 3:结果--->如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数,如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数。

【mov dx ,f】

【mov ax,4241】

【mov bx,2710】

【div bx】

如果是一个8位数的除法:会将ax 除以 bl 然后将结果放在AL当中

如果是一个16位数的除法:会将ax拼接上dx然后将结果放在ax当中

如果是乘法的话就反过来

汇编语言 ---------> and 和 or指令】

1:and指令逻辑与指令,按位进行运算

例如指令:[没有二进制的话就要先转换为2进制]

mov al , 01100011B --------------------> 63

mov al , 00111011B --------------------> 3B

执行后:al = 00100011B -----------------------------> 23

一位一位的对比,全1为1【与运算】

一位一位的对比,有1就是1,全0为0 【或运算】

2:or指令,逻辑或指令,按位进行或运算

汇编语言是无法直接运行2进制指令的;需要转换为16进制才能进行处理

或运算指令

mov al,01100011B ------------->

mov al,00111011B

执行后的结果为

al = 01111011B --------------> 7b

shr 和 shl 右移与左移指令

【shl 和 shr 左移和右移指令】

shl和shr是逻辑移位指令,shl是逻辑左移指令功能为

  • 1:将一个寄存器或内存单元中的数据向左移位
  • 2:将最后移出的一位写入CF中
  • 3:最低位用0补充

指令:

mov al,01001000b

shl al,1 ----------------------------> 将al中的数据左移一位

执行后的al = 10010000b CF = 0

我们来看一下shl,al,l的操作过程

左移:

原数据: 01001000

左移后: 01001000

【验证左移后的数据】

  • mov al ,48 ------------------------------------> 将48移动到ax寄存器的低四位
  • shl al,1 ----------------------------------------> 将al中的数据左移一位
  • shr al,1 ----------------------------------------> 将al中的数据右移一位

rol ax,1 【rol表示的是循环左移】 ----------------------------> 这个了解即可

ror ax ,1 【循环右移】 ----------------------------> 这个了解即可

rcl ax ,1 【带进位的循环左移】 ------------------------------> 这个了解即可

rcr ax ,1 【带进位的循环右移】 ------------------------------> 这个了解即可

【指令:inc ax】,【指令:dec ax】 ------------------------------------------------> 表示增加1和减少1

这两个指令相当于是c语言中的 x++ 和c语言中的 x --

空指令 ------------------------------------------------> nop 起到了占位的作用

汇编语言:交换指令 xchg ax,bx】

汇编语言取反指令:neg ax】----------------------> ax 刚开始的值为0002 我们观察取反后的值

退出汇编程序

【mov ax,4C】 -----------------------------> 相当于退出汇编的指令

【int 21】 -----------------------------> 相当于退出汇编的指令

【物理地址 = 段地址 * 16 + 偏移地址】

【一个物理地址可以有多个段地址和偏移地址表示方法】

【在汇编里面写东西使用 e 指令, 读取使用 D 命令】

我们看到不同的访问方式地址是一样的:二进制左移4位相当于是16进制左移一位

【DS数据段地址寄存器 + 可以通过数据段地址加上偏移地址的方式实现移动】

mov 以21F0为段地址以60为偏移地址,移动到ax中

1234 【前面的两个表示的是低位,后面的两个表示是高位,应该高低搭配,所以吧34移动到AH吧34移动到AL】

将ds为段地址:0000为偏移地址的数据移动到al当中

汇编语言汇编语言的限制可以将ax移动到ds,但是不能将1000移动给ds】

汇编语言CS和IP寄存器

使用 u 指令可以将寄存器中的数据翻译出来

【CS是一个段地址IP是一个偏移地址他们两个构成了一个实际的地址,这个地址指向一个指令这个指令可以被执行,执行的是内存里面对应的指令】


 

汇编语言中代码和数据是不加区分的】【汇编语言的jmp指令-------------------------------> jmp指令某一合法寄存器,指令的功能为:用寄存器的值修改IP】执行指令[a 2000:0000mov ax,6622mov cx,ax][a 1000:0000mov ax,0123mov ax,0000mov bx,axjmp bx]

[IP和CS表示的是代码将要执行的指针,表示的是以CS为段地址IP为偏移地址地方的代码]

【CS和IP事一个关键的寄存器,是一个代码段寄存器,指示了CPU当前要读取的地址,CS位代码段寄存器,IP为指令指针寄存器,从名称上我们可以看出它们和指令的关系】

汇编语言栈讲解

10009H 的存储地址对应的段地址和位地址

命令 d 1000:9 查看得出以下结果

1000表示的是段地址 9 表示的是位地址【表示的是偏移量】

【在汇编语言中进行压栈:首先会吧位置高为压如栈中,然后才会把位置低的压如栈中】

【pop指令:出栈将栈顶的元素去掉然后赋值给AX】

【SS:SP寄存器:指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶】

汇编语言bp,si,di寄存器】

【adc带进位的加法指令-----------------------> 相当于是由进位和借位】

【cmp指令:比较指令,cmp的功能相当于是减法指令,只是不保存结果】

【sbb指令:带借位的减法指令,利用CF位生记录的借位值】

指令的格式:sbb操作对象1,操作对象2

功能:操作对象1 = 操作对象1 -操作对象2 -CF

比如指令:sbb,ax,bx实现的功能是:(ax)= (ax) - (bx) - CF

汇编语言代码编写编译实战

assume cs:codesg  // assume 假设指令,假设它是某一段寄存器或者程序当中的某一个定义相关段
codesg segment    // 相当于是代码段的别名mov ax,0123Hmov bx,0456Hadd ax,bxadd ax,axmov ax,4c00Hint 21Hcodesg ends      // end 表示汇编程序结束写一个end
end

【 手动的进行编译:修改文件的拓展名为asm-----> asm是汇编语言后面会使用到的拓展名】

打开编译器使用该编译器对刚刚编写的汇编代码进行编译

一路回车下去发现没有错误也没有警告

【使用Link指令进行连接】

【查看文件夹中的文件:出现了一个code.exe的可执行文件,这个文件实际上在我们的电脑中时没有办法执行的】

【DEBUG调用实践:可以看到代码一步步的往下执行,出现我们想要的结果】

【编译加运行后全部的结果】

汇编语言代码循环指令:Loop

汇编语言编程案例:计算2的三次方】

  • 【cx 是一个寄存器同时也有计数的功能-------> 可以通过cx得到循环的次数】
  • 【loop指令的使用格式是:loop标号,CPU执行LOOP指令的时候需要进行两步的操作,第一步是:(cx) = (cx) -1,第二步:判断cx当中的值,不为0则转至标号处理程序,如果为0向下执行】
assume cs:codesg 
codesg segment    mov ax,2mov cx,11s:add ax,axloop sint 21Hcodesg ends     
end

【编译运行程序之后一直往下执行】

【代码的存储位置是以076A:0000,以076A为段地址0000为位地址的位置---> 这里使用的是u指令进行查看】

【汇编指令:使用debug一次性执行出结果------------> 使用g指令一次性的执行,g指令的含义 g 0012 含义是cs : 0012 前的程序段被执行,从各个寄存器的值可以看出执行结果】

汇编语言P指令:loop循环中使用p命令来执行,Debug就会自动重复的执行循环中的指令知道CX = 0 为止,跳过循环指令】

【程序++的执行结果: c++的写法可以在汇编语言中一模一样的写出来一个的】

assume cs:codesg 
codesg segment    mov ax,0mov bx,0mov cx,100s:inc axadd bx,axloop sint 21Hcodesg ends     
end

【c++中的一些经典的算法问题都可以在汇编语言中很好的表现出来】

使用vscode编写汇编程序:安装vscode插件

参考网址 : 如何在vscode中编写汇编语言并在终端进行调试(保姆级别)_vscode写汇编语言-CSDN博客文章浏览阅读3.4w次,点赞81次,收藏250次。1)下载and安装vscodehttps://blog.csdn.net/Zhangguohao666/article/details/105665412/2)下载插件:MASM/TASM(如图所示) (1)点击红色箭头处,出现输入框 (2)在蓝色箭头的框中输入MASM,选择MASM/TASM插件进行安装 3)此时可以运行.asm程序,但不能在vscode终端中进行debug,原因是MASM/TASM汇编工具默认是tas..._vscode写汇编语言https://blog.csdn.net/m0_46973282/article/details/109250859

修改配置文件

【后面发现修改这两个配置文件会发生错误】

【编译代码后出现了以下的这个错误】

【实际的解决办法是对程序的插件做出如下修改】

【编译后代码的执行和调试结果】

【尝试一下官方的解决方案】

官方网址: Troubleshoot Visual Studio Code Integrated Terminal launch failuresTroubleshoot Visual Studio Code Integrated Terminal launch failuresicon-default.png?t=N7T8https://code.visualstudio.com/docs/supporting/troubleshoot-terminal-launch

【这个是汇编修改后的代码】

汇编语言中函数的使用call 和 ret函数

【打开终端执行相关的代码】

【编译运行汇编代码】

【执行到loop循环后使用p指令一步得到循环的结果】

汇编语言--函数--就是代码的封装------->函数封装后的写法】

assume cs:codesg 
codesg segment    mov ax,2mov cx,3call s  int 21Hs:add ax,axloop sret
codesg ends     
end

【代码不缩进但实际使用u指令查看内存空间实际上是-----连续的-------】

【注:函数在内存空间中的存储顺序时顺着存储的】

【程序封装的解释:会回到 add ax,ax的位置,IP地址指向的位置就是死循环】

汇编语言:在汇编语言中可以简单的封装一个函数使用的是call 和 ret ------ > 在汇编语言中call相当于是c++ 中的 -----f() ---- ret相当于数c++中的return作用是返回到调用它的那个地方,这个课时掌握的内容是如何编写一个函数即可】

call 指令 和ret 指令的本质

def: call 指令和ret指令都是转移指令,他们都修改IP,或同时修改CS和IP,他们经常被用来实现子程序的设计“本次课的目的是了解call指令和ret指令的原理”

【ret 和retf】 -------------------------> 一个是近转移,一个是远转移

{

【ret 指令的用法:指令用栈中的数据,修改IP的内存,从而实现近转移】

【retf指令的用法:指令使用栈中的数据,修改CS 和IP中的内容,从而实现远距离的转义】

【call指令也有一个call 和一个callf,一个是用来实现近距离的转移,一个是用来实现远距离的转移】

这两个指令的本质就是压栈,但是应该将什么东西压到栈里面和内部机制是如何操作的

}

汇编语言中栈的表示方法SS:SP寄存器表示的是栈的顶部】

assume cs:codesg 
codesg segment    mov ax,2mov cx,3call s  inc bxinc dxint 21Hs:add ax,axloop sret
codesg ends     
end

【编译和运行代码】

使用u指令查看程序执行指令

【使用 r 指令自定义栈的空间 主要是修改 ss 和 sp】

【使用T 指令执行一下--------------> 然后查看指令的执行结果】

【ret 的本质是pop的过程也就是栈的弹出过程(把栈的内容也就是地址的值赋值给IP),CALL是push的过程也也就是压栈的过程()】

汇编语言的retf 和 callf】

assume cs:codesg 
codesg segment    mov ax,3mov cx,11call far ptr s  inc bxinc dxint 21Hs:add ax,axloop sret
codesg ends     
end

【程序的指令】

【修改栈的指针 r ss 和 r sp】

【使用 u 指令查看寄存器中存放的代码】


http://www.ppmy.cn/embedded/12149.html

相关文章

Swift-28-值和引用类型、内存管理以及objectivc与swift混合调用

本小节的内容稍有点多,这三块内容基本没太大关系,只是笔者想在这一节中把swift的oop收下尾,所以全写在一起了。 值类型和引用类型 和其它语言一样,函数调用时对于参数到底是指针引用还是类似String这样的值传递(不可变…

Python构建学生信息管理系统:需求分析与规划

构建学生信息管理系统:需求分析与规划 在软件开发的初期,进行需求分析与规划是至关重要的一步。它不仅帮助开发者明确项目目标,还能确保最终产品能够满足用户的需求。本文将介绍如何使用Python语言,结合常规网络框架、RESTful技术…

【洛谷 P8605】[蓝桥杯 2013 国 AC] 网络寻路 题解(图论+无向图+组合数学)

[蓝桥杯 2013 国 AC] 网络寻路 题目描述 X X X 国的一个网络使用若干条线路连接若干个节点。节点间的通信是双向的。某重要数据包,为了安全起见,必须恰好被转发两次到达目的地。该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种…

iOS ------代理 分类 拓展

代理协议 一,概念: 代理,又称委托代理(delegate),是iOS中常用的一种设计模式。顾名思义,它是把某个对象要做的事委托给别的对象去做。那么别的对象就是这个对象的代理,代替它来打理…

第三讲-流程挖掘(Process Mining)学习日志之数据挖掘详解(上)

第三讲 数据挖掘详解(上) 文章目录 第三讲 数据挖掘详解(上)3.1 数据挖掘技术的分类3.1.1 数据集:实例与变量3.1.2 有监督学习:分类与回归3.1.3 无监督学习:聚类与模式发现 3.2 决策树学习3.3 k…

uniapp APP检测更新

需求: 1.首次进入APP给出弹窗提示是否存在最新版本APP,可选择更新或者取消 2.选择取消后,在使用期间不再弹出该弹窗 3.在设置中增加按钮,点击进行版本检测,再弹窗 效果图: 使用到的插件:APP升…

【QT进阶】Qt http编程之http与https简单介绍

往期回顾 【QT进阶】Qt Web混合编程之html、 js的简单交互-CSDN博客 【QT进阶】Qt Web混合编程之使用ECharts显示各类折线图等-CSDN博客【QT进阶】Qt Web混合编程之实现ECharts数据交互动态修改-CSDN博客 【QT进阶】Qt http编程之http与https简单介绍 一、什么是http与https …

FPV眼镜和VR眼镜的区别,穿越机搭配FPV眼镜优缺点分析

FPV眼镜,即第一人称视角(First Person View)眼镜,是专为无人机、穿越机、遥控模型等飞行设备设计的头戴式显示器。这种设备能够将飞行设备上的摄像头所捕捉的实时图像传输到眼镜中,让佩戴者仿佛亲自驾驶飞行器一样&…