XMU汇编语言实验04:程序流程控制

本次实验主要针对一些程序结构的运用。其实本次实验相对难度比较低,只需要先用高级语言写一遍再翻译成汇编就可以(因为本次实验并未涉及到某些高级语言特性)。

实验内容

(2) 根据下述情况,分别编写程序,记录 BX 中 1 的个数(需要考虑 BX 中二进制 串的特殊情况),要求如下:

⚫ 循环次数已知

⚫ 循环次数未知

 (3) 按照下列要求,编写相应程序段。

1) 起始地址为 string 的主存单元中存放一个字符串(长度大于 6),把该字符串中的第 1 个和第 6 个字符(字节量)传送给 DX 寄存器;

2) 从主存 buffer 开始的 4 字节中保存了 4 个非压缩 BCD 码,现按低(高) 地址对低(高)位的原则,将他们合并到 DX 中。

3) 假设从 B800H:0 开始存放有 100 个 16 位无符号数,编程求它们的和,并 存在 DX.AX 中

 4) 一个 100 字节元素的数组首地址为 array,将每个元素减 1(不考虑溢出)。

 (4) 把内存中从 PACKED 开始的 10 个字节单元中的 16 位压缩 BCD 数转换成非压 缩 BCD 数,并把结果存放在 UNPACKED 开始的 20 个字节单元中;将下列代 码补充完整,并且自己定义 PACKED 中的数据,将 UNPACKED 中的结果展示 出来。 MOV DX, _____ MOV CL, ______ MOV SI, 0 MOV DI, ___ CONVERT: MOV AL, [SI+PACKED] MOV AH, AL AND AL, 0FH __________ MOV [DI+UNPACKED], ____ ADD DI, ____ ______ DEC DX JNZ CONVERT

 (5) 给定一个有序数组(均小于 FFH 例如 02H, 07H, 0BH, 0FH, 13H, 1CH, 24H, 39H, 40H, 57H, 68H)和一个目标值(例如 79H),请判断数组中是否含有两个数的 和为目标值,请设计一个算法,将时间复杂度控制在 O(n),编程实现并验证 你的算法。

实验可能遇见的问题

        (2)要求自行别写一个程序循环对BX进行操作,可以简单地写个对BX进行移位的实验。

比如本人写的是当BX小于某个数时停止循环,这就是一个未知次数的循环,使用JMP和JCC控制。

try: shr bx,1
    cmp bx,1000
    jb next
    jmp try
next: ...

        (3)

        2)可以使用移位指令和OR指令进行压缩。例如:

.model small
.data
	buffer dw 0009h,0008h,0007h,0006h
.stack
.code
.startup
mov ax,buffer
mov cl,12
shl ax,cl
mov si,2
mov dx,buffer[si]
mov cl,8
shl dx,cl
or ax,dx
add si,2
mov dx,buffer[si]
mov cl,4
shl dx,cl
or ax,dx
add si,2
mov dx,buffer[si]
or ax,dx
mov dx,ax
.exit
end

注意CL的向左移位次数。当然,这个程序相对臃肿,但是理解起来很简单。

3)你可以循环初始化所有数据(或者干脆不初始化),直接写求和代码。

(4)不多废话,直接看代码。

.MODEL SMALL
.DATA
    PACKED dw 0123h,1234h,2345h,6789h,7890h
    unpacked dw 10 dup(?)
.STACK
.CODE
.STARTUP
     mov dx,10	;设置循环次数
     mov cl,4	;循环移位位数为4
     mov si,0
     mov di,0	;起始偏移量为0
     convert:mov al,byte ptr[si+packed]
     mov ah,al
     and al,0fh		
     shr ah,cl	;高四位要移到低四位
     mov [di+unpacked],ax	;整个字传送
     add di,2	;对应非压缩要移动2字节
     mov ax,0
     inc si	
     dec dx	;压缩移动1字节
     jnz convert
     
.EXIT
     END

(5)这是双指针算法的汇编实现。网上查下C语言的对撞指针实现,然后翻译成汇编即可。

;双指针算法汇编实现
;如果可以输出两个数,不可以输出空
.MODEL SMALL
.DATA
    array db 02h,07h,0bh,0fh,13h,1ch,24h,39h,40h,57h,68h
    target db 37h
.STACK
.CODE
.STARTUP
   lea bp,array		;bp左指针
   lea bx,array+sizeof array-1	;bx右指针
 try:mov al,[bp]
 	add al,[bx]
 	cmp al,target	;比较bp+bx和target
 	jb bpp		;若小于,则bp++
 	jz quit		;若等于,则输出
 	dec bx
 	cmp bx,bp
 	jb ending		;大于target时,bx--,当bx小于bp,说明找不到
 	jmp try		;继续比较
bpp:inc bp
	cmp bp,bx
	jnbe ending	;当bp大于bx,说明找不到,直接退出
 	jmp try		;继续比较
quit:
	mov dl,[bp]
	mov cl,4
	shr dl,cl
	add dl,30h
	mov ah,2
	int 21h
	mov dl,[bp]
	and dl,0fh
	add dl,30h
	mov ah,2
	int 21h
	mov dl,10
	mov ah,2
	int 21h
	mov dl,[bx]
	shr dl,cl
	add dl,30h
	mov ah,2
	int 21h
	mov dl,[bx]
	and dl,0fh
	add dl,30h
	mov ah,2
	int 21h
	mov dl,10
	mov ah,2
	int 21h
ending:
	mov ah,4ch
	int 21h
.EXIT
     END

上面代码看起来很长的原因主要是控制输出格式导致的(你看到下面很多mov ah,2 /int 21h)。

总结:

        上面代码不是最简洁的形式,你可以使用一些高级的伪指令写出更简洁的代码惊艳你的老师(但是并没有什么用),本文除了变量定义伪指令和简化段定义,其他几乎都使用硬指令来完成。虽然并不高效,但胜在好懂。欢迎各位有更好的想法指正。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值