学汇编,记笔记(四)——[BX]和loop

前言

学习教材:《汇编语言(第3版)》王爽著
此笔记是书中内容+自我总结,方便查阅和复习
请支持原著

约定[bx]符号、(bx)符号、idata符号

前面提到,[0]可以表示某段偏移地址为0的那个内存单元,它有自适应功能:

mov ax,[0] //表示将字单元[0]和[1]传入ax
mov al,[0] //表示将字节单元[0]传入al

因此,类似于上面的用法:[bx]表示某段偏移地址为bx值的那个内存单元,此时偏移地址存在bx内

为了区分且使描述方便,定义(bx)表示bx存储的内容,可以是寄存器(ax)、段寄存器+偏移地址((ds)*16+(bx))和内存单元(10000H)

(2000:0)、((ds):1000H)等是错误用法,必须前后统一

idata表示任意常量,可以是1,2,3,…

文章目录

  • 前言
    • 约定[bx]符号、(bx)符号、idata符号
  • 一、loop
    • 实验:加法循环计算123*236
  • 二、遍历连续的内存单元
  • 三、Debug.exe和MASM的不同处理
  • 四、段前缀
  • 五、安全的内存
  • 后记

一、loop

loop指令表示循环,循环次数存储在寄存器cx里,格式为loop 标号,在循环体的第一行添加标号以表明循环入口。这是一个两次自增的循环:

assume cs:cal
cal segment
	;初始化
	mov ax,1
	mov cx,2
	;循环体
	s:add ax,ax
	loop s
	;返回值
	mov ax,4c00h
	int 21h
test ends
end

CPU执行Loop指令时分作两步

  1. (cx) -= 1
  2. 判断cx是否为0,不为0则转至运行标号处代码,否则向下执行

实验:加法循环计算123*236

累加123个236即可得到答案

assume cs:cal
cal segment
	mov ax,0
	mov cx,123
	s:add ax,236
	loop s
	mov ax,4c00h
	int 21h
cal ends
end

二、遍历连续的内存单元

假设需要遍历FFFF:0~FFFF:B这十二个内存单元,累加它们的值放到dx,传统方法是写十二个add,这里我们可以用循环

inc指令表示将某寄存器的值加一,如inc bx

需要注意的是:

  • 内存单元是一字节,而ax是十六位寄存器,存储元件的数据长度不一样不能直接赋值,因此需要分别对ah赋值0,对al赋值(FFFF:[bx]), 其他方法可能会引起进位丢失等情况

  • 汇编源程序中,数据不能以字母开头,FFFFH要写作0FFFFH

     assume cs:ffff0_12
     ffff0_12 segment
     	mov ax,0FFFFH
     	mov ds,ax
    
     	mov bx,0
     	mov cx,12
     	mov dx,0
     	
     	s:mov al,[bx]
     	mov ah,0
     	add dx,ax
     	inc bx
     	loop s
     	
     	mov ax,4c00h
     	int 21
     	
     ffff0_12 ends
     end
    

三、Debug.exe和MASM的不同处理

对于mov ax,[0],希望表示将ds:0内存单元的值送入ax,然而:

  • MASM会将其当作mov ax,0
  • Debug.exe会将其当作mov ax,ds:0

为了避免歧义,建议使用以下形式:

  1. mov al,ds:[0],(al)=((ds)*16+0)
  2. mov al,[bx],其中bx=0,(al)=((ds)*16+(bx))

四、段前缀

由于上方提到的差异处理,建议对偏移地址均添加对应的段前缀,避免歧义且便于理解

  • mov ax,ds:[bx/0]
  • mov ax,cs:[bx/0]
  • mov ax,ss:[bx/0]
  • mov ax,es:[bx/0]

五、安全的内存

随意向任意内存写入内容是危险的!

在一般的PC机中,DOS模式下安全的空闲的空间是00200H~002FFH,总长256B,可以供我们操作

谨慎起见,使用前先Debug查询,只有全是0才能安全使用

后记

  1. 编程中发现segment不能命名为test(?存疑)
  2. loop的原理是先减再判定再执行
  3. cx记录循环次数
  4. 良好的习惯:段前缀
  5. 不要随意写入
  6. 内存单元到寄存器的数据送入需要分两段送入,前者大小1B,后者大小2B

你可能感兴趣的:(学汇编,记笔记,8086,汇编,汇编程序,计算机,MASM)