继续搞汇编!!

原创 程序员cxuan 2023-01-06 08:00

这是汇编第五篇文章了昂,前四篇如下

爱了爱了,这篇寄存器讲的有点意思

没错!cxuan 对汇编下手了

手把手教你汇编 Debug

手撕汇编。。。

之前的文章中介绍过 [0] 表示的是偏移地址为 0 的内存单元 。比如下面的指令

mov ax,[0]

就是将一个内存单元的内容送入 ax,这个内存单元的长度为 2 个字节,是一个字型数据,偏移地址为 0 ,段地址在 ds 中,也就是这个内存单元的地址是 ds:0 ,它的物理地址是 (ds * 16 + 0)H。

除了可以传输字型数据,还可以传输字节型数据,比如下面代码

mov al,[0]

就是将一个内存单元的地址送入 al 中,这个内存单元的长度是 1 字节,存放字节型数据,偏移地址为 0 ,段地址在 ds 中,大白话说也就是将 ds:0 处的一个字节传入到 al 中。

从上面两个例子可以看出,假如要描述一个完整的一个内存单元,应该需要两种信息:即内存单元的地址和内存单元的长度

比如我们要读取一个 10000H 的数据,你可能会需要下面这段代码。

mov bx,1000H 	#将 1000H 放入 bx 寄存器中
mov ds,bx #将段寄存器 ds 的值设为 1000H
mov al,[0] #从内存单元 1000:0 处读出1字节内容放入 al 中。

但是表示内存地址的方式除了能够直接指定其内存地址之外,还可以用一种间接寻址的方式,这就是 [bx],它表示的是一种寄存器间接寻址,也是一种偏移地址,同样的,比如我们要读取一个物理地址为 10001H 处的数据,使用 [bx] 这种方式的代码如下

mov ax,1000H
mov ds,ax
mov bx,1
mov ax,[bx]

这样计算机就会寻找段地址为 1000H,偏移地址为 0001H 的数据放入到 ax 中。

它的中文解释就是 把 [bx] 指向的地址中的内容,送入 ax 寄存器中

比如下面这段代码

mov ax,[bx]

它表示的就是将偏移地址为 bx 的数据,送入到 ax 中,送入的是 2 个字节,也就是字型数据。

又比如下面这段代码

mov al,[bx]

它表示的就是将偏移地址为 bx 的数据,送入到 al 中,送入的内存单元地址是 1 个字节的字节型数据。

[bx] 这种间接寻址的好处就是每次偏移地址不是固定的,这为我们接下来的循环指令奠定了基础。

( ) 表示法

为了更方便的描述后面,我们使用 () 来表示一个寄存器或者内存单元中的内容。

这里需要注意一下,( ) 内的能够表示的内容一般有三种类型:

  • 寄存器名,比如 (ax) 就表示 ax 中的内容,(al) 就表示 al 中的内容。
  • 段寄存器名,比如 (ds) 就表示段寄存器 ds 中的内容。
  • 内存单元的物理地址,比如 ((ds) * 16 + (bx)),一个 20 位的数据。

我们知道,寄存器存储的数据类型有两种,字型和字节型,字型数据一般用 ax 这类寄存器来存储,字节型数据一般用 ah 、al 这种寄存器来存储。

同样的,( ) 内的数据类型也有两种,字型和字节型。比如 (al)、(bl)、(cl) 这种表示的数据就是字节型,而 (ax)、(bx)、(cx) 表示的数据就是字型。下面是几类 ( ) 的一些用法:

  • ax 中的内容为 0020H:(ax) = 0020H;
  • 2000:1000 处的内容为 0010H:(21000H) = 0010H;
  • mov ax,[2] 则表示为:ax = ((ds * 16) + 2);
  • mov [2],ax 则表示为:((ds) * 16 + 2) = (ax);
  • add ax,2 表示为:(ax) = (ax) + 2;
  • push ax 表示为:(sp) = (sp) - 2, ((ss * 16) + sp) = (ax);
  • pop ax 表示为:(ax) = ((ss) * 16) + sp), (sp) = (sp) + 2;

idata

idata 表示的就是立即数,这个概念就更简单了,立即数顾名思义就是直接的数字,也就是常量。比如 mov ax,[0] ,其中的 0 就是立即数,即 idata = 0 ,所以 [立即数] = [idata],所以以后我们通常使用 idata 来表示常量,比如下面几个例子

  • mov ax,[idata] 可以表示为 mov ax,[1] mov ax,[2] mov ax,[3]
  • mov ax,idata 可以表示为 mov ax,1    mov ax,2    mov ax,3

知道上面是 啥意思了吧?

[BX]

再来啰嗦一下 [bx] 的寻址方式,比如下面代码

mov ax,[bx]

bx 中存放的数据作为一个偏移地址,这里用 EA 表示(没有其他意思,只是单纯地表示偏移地址),段地址在 ds 中,用 SA 表示(同 EA 的解释),将 SA:EA 处的数据送入 ax 中,即 (ax) = ((ds) * 16 + (bx))。

可以将内存单元送入寄存器中,也可以将寄存器的数据送入到内存单元中,如下代码所示

mov [bx],ax

就是将 ax 中的数据送入到 SA:EA 处,即 ((ds) * 16 + (bx)) = (ax)。

为了让大家加深对 [bx] 的认识,我们通过一些汇编指令来认识一下程序的执行过程,代码如下

mov ax,2000H
mov ds,ax
mov bx,1000H
mov ax,[bx]
inc bx
inc bx
mov [bx],ax
inc bx
inc bx
mov [bx],ax
inc bx
mov [bx],al
inc bx
mov [bx],al

初始内存示意图:

下面我们就按照每一行指令来分析一下

首先,mov ax,2000H 就是将 2000 送入 ax 中,mov ds,ax 就是将设置段地址为 2000 H,mov bx,1000H 就是将 1000 送入 bx 中,mov ax,[bx] 就是将 2000:1000 处的地址送入到 ax 中(因为段基址为 2000,偏移地址 dx 为 1000),2000H:1000H 处的指令是 00be,所以 ax = 00BEH ,存储字型数据。

inc bx 就是将寄存器 bx 的值加 1,此处有两条 inc 指令,所以执行完成后 bx = 1002H,此处段基址:偏移地址为 2000H:1002H。

然后下面 (第七行指令)mov [bx],ax 就是将 ax 中的数据送入到 [bx] 中,也就是 1002H 处,指令执行后,2000:1002 单元的内容为 BE,2000:1003 单元的内容为 00,存放字型数据,执行完成后的示意图如下

继续执行第 8、9 行的指令,inc bx ,执行完成后 bx = 1004H,然后执行第 10 行指令 mov [bx],ax ,指令执行前:ds = 2000H,bx = 1004H,mov [bx],ax 相当于是把 ax 中的数据送到 2000:1004 处,指令执行完成后,2000:1004 的单元内容为 BE ,如下示意图所示

接下来执行第 11 行指令,inc bx,执行完成后 bx = 1005H,mov [bx],al 是把 al 中的数据送入内存 2000:1005 处,指令执行完成后,2000:1005 处的单元内容为 BE,如下示意图所示

继续执行指令,第13、14 行指令和 11 、12 行指令一样,它的意思就是将 bx 的值加一之后,将 al 的值送入到指定地址处,执行完成后的 ds = 2000H,bx = 1006H,所以 2000:1006 处的内容是 BE(al 存储的数据),示意图如下

想必大家跟完上面的流程后,应该对 [bx] 这个间接寻址方式有了比较深刻的认识。

下面想个问题,使用汇编编程计算 2 * 2 ,并将结果存储在 ax 寄存器中。

这个思路还是比较简单的,直接将 2 放在 ax 寄存器中,然后执行 ax 的 add 操作就可以了,下面是汇编代码

assume cs:codesg
codesg segment
mov ax,2
add ax,ax

mov ax,4c00h
int 21h
codesg ends
end

上面这段代码中的计算量还比较低,但是如果要让你计算 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 呢,你难道要写 n 个 add ax,ax 吗?

assume cs:codesg
codesg segment
mov ax,2
add ax,ax
add ax,ax
add ax,ax
add ax,ax
。。。

mov ax,4c00h
int 21h
codesg ends
end

这就很繁琐啊,所以不能这么玩,那该怎么搞呢?这里就需要一种能够循环之星 add ax,ax 的指令了,这个指令就是 Loop

Loop 指令

Loop 指令能够循环判断是否执行指定的指令,它的执行流程就相当于我们 Java 中的 for 循环。

我们先来使用 Loop 改写一下上面 n 个 2 相乘的代码,然后再讲解一下 Loop 的使用。

assume cs:codesg
codesg segment
mov ax,2
mov cx,8
s: add ax,ax
loop s

mov ax,4c00h
int 21h
codesg ends
end

可以看到,我们使用 8 个 2 相乘的代码被优化的这么简单,这就是 loop 指令的精髓所在。

其实关键代码就是三条指令,即

  • mov cx,8
  • s: add ax,ax
  • loop s

翻译过来的意思就是将 8 放在 cx 中,然后给 add ax,ax 处设置一个标号,然后执行 s 循环。

loop 指令的格式是:loop 标号,CPU 执行 loop 指令的时候,要进行两步操作,第一步:(cx) = (cx) - 1,第二步:判断 cx 的值,不为 0 则转至标号(上面代码是 s)处继续执行指令,如果为 0 则向下执行(上面代码中乡下继续执行就是 mov ax,4c00h)。上面代码中,我们把 8 送入了 cx 中,也就是说,cx 中存储的就是执行次数。

下面我们详细介绍一下上面这段程序的执行过程,从中体会一下 cx 和 loop s 是如何配合实现循环的。

(1) 执行 cx,8 ,设置 cx = 8

(2) 执行 add ax,ax(第 1 次)

(3) 执行 loop s 将 cx 的值 - 1,此时 (cx) = 7,(cx) != 0 ,所以转至 s 处

(4) 执行 add ax,ax(第 2 次)

(5) 执行 loop s 将 cx 的值 - 1,此时 (cx) = 6,(cx) != 0 ,所以转至 s 处

(6) 执行 add ax,ax(第 3 次)

(7) 执行 loop s 将 cx 的值 - 1,此时 (cx) = 5,(cx) != 0 ,所以转至 s 处

(8) 执行 add ax,ax(第 4 次)

(9) 执行 loop s 将 cx 的值 - 1,此时 (cx) = 4,(cx) != 0 ,所以转至 s 处

(10) 执行 add ax,ax(第 5 次)

(11) 执行 loop s 将 cx 的值 - 1,此时 (cx) = 3,(cx) != 0 ,所以转至 s 处

(12) 执行 add ax,ax(第 6 次)

(13) 执行 loop s 将 cx 的值 - 1,此时 (cx) = 2,(cx) != 0 ,所以转至 s 处

(14) 执行 add ax,ax(第 7 次)

(15) 执行 loop s 将 cx 的值 - 1,此时 (cx) = 1,(cx) != 0 ,所以转至 s 处

(16) 执行 add ax,ax(第 8 次)

(15) 执行 loop s 将 cx 的值 - 1,此时 (cx) = 0,(cx) == 0 ,所以转至 s 处

(16) 执行 mov ax,4c00h(循环结束)

从上面这个过程中,我们可以总结处用 cx 和 loop 指令相配合实现循环功能的 3 点注意事项:

  • 在 cx 中存放循环次数。
  • loop 指令中的标号所标识的地址要在前面
  • 要循环执行的程序段,要写在标号和 loop 指令的中间。

所以综上所述,使用 Loop 和 cx 相配合实现的循环功能的结构如下:

	mov cx,循环次数
s:
循环执行的程序段
loop s

比如我们想用 Loop 循环计算出 123 * 456 这个值,就可以使用这种方式

assume cs:codesg
codesg segment
mov ax,0
mov cx,456
s:add ax,123
loop s

mov ax,4c00h
int 21h
codesg ends
end

预告

能滑到这里的都是真爱!!

最近我正在汇总一个汇编语言的超清超全脑图,到时候等文章完结之后会免费给大家放出来可供学习,先来个预告版本:

各位小伙伴们敬请期待下~!!!!

程序员cxuan cxuan 写的文章还不错。会分享计算机底层、计算机网络、操作系统,Java基础、框架、源码等文章。
评论 (0)
  • 文/郭楚妤编辑/cc孙聪颖‍相较于一众措辞谨慎、毫无掌舵者个人风格的上市公司财报,利亚德的财报显得尤为另类。利亚德光电集团成立于1995年,是一家以LED显示、液晶显示产品设计、生产、销售及服务为主业的高新技术企业。自2016年年报起,无论业绩优劣,董事长李军每年都会在财报末尾附上一首七言打油诗,抒发其对公司当年业绩的感悟。从“三年翻番顺大势”“智能显示我第一”“披荆斩棘幸从容”等词句中,不难窥见李军的雄心壮志。2012年,利亚德(300296.SZ)在深交所创业板上市。成立以来,该公司在细分领
    华尔街科技眼 2025-05-07 19:25 350浏览
  • 硅二极管温度传感器是一种基于硅半导体材料特性的测温装置,其核心原理是利用硅二极管的电学参数(如正向压降或电阻)随温度变化的特性实现温度检测。以下是其工作原理、技术特点及典型应用:一、工作原理1、‌PN结温度特性‌硅二极管由PN结构成,当温度变化时,其正向电压 VF与温度呈线性负相关关系。例如,温度每升高1℃,VF约下降2 mV。2、‌电压—温度关系‌通过jing确测量正向电压的微小变化,可推算出环境温度值。部分型号(如SI410)在宽温域内(如1.4 K至475 K)仍能保持高线性度。
    锦正茂科技 2025-05-09 13:52 115浏览
  • 文/Leon编辑/cc孙聪颖‍《中国家族企业传承研究报告》显示,超四成“企二代” 明确表达接班意愿,展现出对家族企业延续发展的主动担当。中国研究数据服务平台(CNRDS)提供的精准数据进一步佐证:截至 2022 年,已有至少 280 家上市家族企业完成权杖交接,其中八成新任掌门人为创始人之子,凸显家族企业代际传承中 “子承父业” 的主流模式。然而,对于“企二代” 而言,接棒掌舵绝非易事。在瞬息万变的商业环境中,他们既要在白热化的市场竞争中开拓创新、引领企业突破发展瓶颈,又需应对来自父辈管理层的经
    华尔街科技眼 2025-05-06 18:17 27浏览
  • UNISOC Miracle Gaming奇迹手游引擎亮点:• 高帧稳帧:支持《王者荣耀》等主流手游90帧高画质模式,连续丢帧率最高降低85%;• 丝滑操控:游戏冷启动速度提升50%,《和平精英》开镜开枪操作延迟降低80%;• 极速网络:专属游戏网络引擎,使《王者荣耀》平均延迟降低80%;• 智感语音:与腾讯GVoice联合,弱网环境仍能保持清晰通话;• 超高画质:游戏画质增强、超级HDR画质、游戏超分技术,优化游戏视效。全球手游市场规模日益壮大,游戏玩家对极致体验的追求愈发苛刻。紫光展锐全新U
    紫光展锐 2025-05-07 17:07 277浏览
  • Matter协议是一个由Amazon Alexa、Apple HomeKit、Google Home和Samsung SmartThings等全球科技巨头与CSA联盟共同制定的开放性标准,它就像一份“共生契约”,能让原本相互独立的家居生态在应用层上握手共存,同时它并非另起炉灶,而是以IP(互联网协议)为基础框架,将不同通信协议下的家居设备统一到同一套“语义规则”之下。作为应用层上的互通标准,Matter协议正在重新定义智能家居行业的运行逻辑,它不仅能向下屏蔽家居设备制造商的生态和系统,让设备、平
    华普微HOPERF 2025-05-08 11:40 282浏览
  • 温度传感器的工作原理依据其类型可分为以下几种主要形式:一、热电阻温度传感器利用金属或半导体材料的电阻值随温度变化的特性实现测温:l ‌金属热电阻‌(如铂电阻 Pt100、Pt1000):高温下电阻值呈线性增长,稳定性高,适用于工业精密测温。l ‌热敏电阻‌(NTC/PTC):NTC 热敏电阻阻值随温度升高而下降,PTC 则相反;灵敏度高但线性范围较窄,常用于电子设备温控。二、热电偶传感器基于‌塞贝克效应‌(Seebeck effect):两种不同
    锦正茂科技 2025-05-09 13:31 106浏览
  • 二位半 5线数码管的驱动方法这个2位半的7段数码管只用5个管脚驱动。如果用常规的7段+共阳/阴则需要用10个管脚。如果把每个段看成独立的灯。5个管脚来点亮,任选其中一个作为COM端时,另外4条线可以单独各控制一个灯。所以实际上最多能驱动5*4 = 20个段。但是这里会有一个小问题。如果想点亮B1,可以让第3条线(P3)置高,P4 置低,其它阳极连P3的灯对应阴极P2 P1都应置高,此时会发现C1也会点亮。实际操作时,可以把COM端线P3设置为PP输出,其它线为OD输出。就可以单独控制了。实际的驱
    southcreek 2025-05-07 15:06 425浏览
  • 后摄像头是长这个样子,如下图。5孔(D-,D+,5V,12V,GND),说的是连接线的个数,如下图。4LED,+12V驱动4颗LED灯珠,给摄像头补光用的,如下图。打开后盖,发现里面有透明白胶(防水)和白色硬胶(固定),用合适的工具,清理其中的胶状物。BOT层,AN3860,Panasonic Semiconductor (松下电器)制造的,Cylinder Motor Driver IC for Video Camera,如下图。TOP层,感光芯片和广角聚焦镜头组合,如下图。感光芯片,看着是玻
    liweicheng 2025-05-07 23:55 297浏览
  • 这款无线入耳式蓝牙耳机是长这个样子的,如下图。侧面特写,如下图。充电接口来个特写,用的是卡座卡在PCB板子上的,上下夹紧PCB的正负极,如下图。撬开耳机喇叭盖子,如下图。精致的喇叭(HY),如下图。喇叭是由电学产生声学的,具体结构如下图。电池包(AFS 451012  21 12),用黄色耐高温胶带进行包裹(安规需求),加强隔离绝缘的,如下图。451012是电池包的型号,聚合物锂电池+3.7V 35mAh,详细如下图。电路板是怎么拿出来的呢,剪断喇叭和电池包的连接线,底部抽出PCB板子
    liweicheng 2025-05-06 22:58 527浏览
  • 在过去的很长一段时间里,外卖市场呈现出美团和饿了么双寡头垄断的局面。美团凭借先发优势、强大的地推团队以及精细化的运营策略,在市场份额上长期占据领先地位。数据显示,截至2024年上半年,美团外卖以68.2%的市场份额领跑外卖行业,成为当之无愧的行业老大。其业务广泛覆盖,从一线城市的繁华商圈到二三线城市的大街小巷,几乎无处不在,为无数消费者提供便捷的外卖服务。饿了么作为阿里本地生活服务的重要一环,依托阿里强大的资金和技术支持,也在市场中站稳脚跟,以25.4%的份额位居第二。尽管市场份额上与美团有一定
    用户1742991715177 2025-05-06 19:43 63浏览
  • 飞凌嵌入式作为龙芯合作伙伴,隆重推出FET-2K0300i-S全国产自主可控工业级核心板!FET-2K0300i-S核心板基于龙芯2K0300i工业级处理器开发设计,集成1个64位LA264处理器,主频1GHz,提供高效的计算能力;支持硬件ECC;2K0300i还具备丰富的连接接口USB、SDIO、UART、SPI、CAN-FD、Ethernet、ADC等一应俱全,龙芯2K0300i支持四路CAN-FD接口,具备良好的可靠性、实时性和灵活性,可满足用户多路CAN需求。除性价比超高的国产处理器外,
    飞凌嵌入式 2025-05-07 11:54 65浏览
  • 随着智能驾驶时代到来,汽车正转变为移动计算平台。车载AI技术对存储器提出新挑战:既要高性能,又需低功耗和车规级可靠性。贞光科技代理的紫光国芯车规级LPDDR4存储器,以其卓越性能成为国产芯片产业链中的关键一环,为智能汽车提供坚实的"记忆力"支持。作为官方授权代理商,贞光科技通过专业技术团队和完善供应链,让这款国产存储器更好地服务国内汽车厂商。本文将探讨车载AI算力需求现状及贞光科技如何通过紫光国芯LPDDR4产品满足市场需求。 车载AI算力需求激增的背景与挑战智能驾驶推动算力需求爆发式
    贞光科技 2025-05-07 16:54 190浏览
  • ‌一、高斯计的正确选择‌1、‌明确测量需求‌‌磁场类型‌:区分直流或交流磁场,选择对应仪器(如交流高斯计需支持交变磁场测量)。‌量程范围‌:根据被测磁场强度选择覆盖范围,例如地球磁场(0.3–0.5 G)或工业磁体(数百至数千高斯)。‌精度与分辨率‌:高精度场景(如科研)需选择误差低于1%的仪器,分辨率需匹配微小磁场变化检测需求。2、‌仪器类型选择‌‌手持式‌:便携性强,适合现场快速检测;‌台式‌:精度更高,适用于实验室或工业环境。‌探头类型‌:‌横向/轴向探头‌:根据磁场方向选择,轴向探头适合
    锦正茂科技 2025-05-06 11:36 434浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦