汇编语言设计-实验五(5.6-5.9)

5.6 编写程序,将一个包含有 20 个数据的数组 M 分成两个数组:正数数组 P 和负数数组 N,
并分别把这两个数组中数据的个数显示出来。

DATAS SEGMENT
	STR1 DW 1,-1,-2,8,-9,-8,2,7,11,12,78,65,-12,10,19,23,5,-7,77,88
    N_COU DW 0 ;记录负数的个数
    P_COU DW 0 ;记录正数的个数
    N DW 14H DUP(?) ;存放负数
    P DW 14H DUP(?) ;存放正数
DATAS ENDS

STACKS SEGMENT
	DW 30H DUP(0)
TOP LABEL WORD
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    MOV ES,AX
    MOV AX,STACKS
    MOV SS,AX
    LEA SP,TOP
    LEA SI,STR1
    
    MOV BX,0 ;用于偏移N数组的地址
    MOV DI,0 ;用于偏移P数组的地址,DI是偏移量,初始化为0
    
    ;DI怎么在P和N数组之间进行转化:开两个寄存器记录
    MOV CX,14H
L1: PUSH CX ;循环20次
	MOV AX,[SI]
	CMP AX,0 ;比较是否大于0
	JG P_CODE ;大于0存储到P数组
	;负数
	MOV N[BX],AX ;把数字存放到N数组里
	ADD BX,02H ;指针后移两个字节
	INC N_COU
	JMP NEXT
	
P_CODE:
	;正数
	MOV P[DI],AX ;!!!注意这里DI的使用方法
	ADD DI,02H
	INC P_COU
	
NEXT:
	ADD SI,02H ;源串的指针后移两个字节
	POP CX
	LOOP L1
	
OUT_PUT:
	MOV AX,P_COU ;正数
	CALL PRINT
	
	MOV AH,02H
	MOV DL,0AH
	INT 21H
	
	MOV AX,N_COU ;负数
	CALL PRINT
	
    ;此处输入代码段代码
    MOV AH,4CH
    INT 21H
    
    ;十进制数的输出,除10取余输出
PRINT PROC
	MOV CX,0
PL1:MOV DX,0 ;清零操作
	MOV SI,10
	DIV SI
	PUSH DX ;把余数入栈
	INC CX ;统计数位,便于L2执行输出
	CMP AX,0
	JNE PL1 ;商不为0
	
PL2:POP DX
	ADD DX,30H ;转化为字符类型,为输出做准备
	MOV AH,02H 
	INT 21H
	LOOP PL2
	RET
PRINT ENDP

CODES ENDS
	END START

5.7 试编写一个汇编语言程序,求出首地址为 DATA 的 100D 字数组中的最小偶数,并把它
存放在 AX 中。(此处我的数组中仅有10个数值)

思路:

  1. 使用SI指针来遍历数组A
  2. 初始化AX为极大值来与指针SI所指向的数值比较,每次取更小的偶数
  3. 最后使用十进制输出,验证是否正确

要点:

  1. 特殊处理0值(优化了代码,不加也可以)
  2. 注意保护AX的数值
  3. 利用TEST来测试当前数字是偶数还是奇数。TEST用于按位与操作,若结果为0,则ZF=1;反之,ZF=0
DATAS SEGMENT
    A DW 9,11,12,16,7,3,4,15,99,78 ;定义一个数组  
	  ;DW 90 DUP(?)
DATAS ENDS

STACKS SEGMENT
    DW 100 DUP(?)
TOP LABEL WORD
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    MOV AX,STACKS
    MOV SS,AX
    LEA SP,TOP 
    
    LEA SI,A ;SI指向A数组的首地址
    MOV CX,10
    MOV AX,0FFFH ;初始化为最大有符号数
    
FIND_MIN:
	MOV BX,[SI]
	TEST BX,1 ;测试最低位是否为1,将BX与1按位与,如果结果为0,则ZF=1;反之,ZF=0
	JNZ NEXT_OP ;说明是奇数
	CMP BX,AX 
	JGE NEXT_OP ;有符号,>=
	MOV AX,BX
	; 在FIND_MIN循环后添加
	
NEXT_OP:
	ADD SI,2
	LOOP FIND_MIN
    
    ;输出验证
    MOV BX,AX ;要输出的数
    MOV CX,0 
    
    ;处理0的特殊情况
    CMP BX,0
    JNE OUT_PUT
    MOV DL,'0'
    MOV AH,02H
    INT 21H
    JMP EXIT
    
    MOV AX,BX ;恢复AX的数值
OUT_PUT:
	MOV DX,0 ;DX清零
	MOV SI,10
	DIV SI
	PUSH DX ;存余数
	INC CX
	CMP AX,0 ;比较商值
	JNE OUT_PUT

PRINT_OP:
	POP DX
	ADD DL,30H ;转化为字符型
	MOV AH,02H
	INT 21H
	LOOP PRINT_OP 
    
    ;结束
EXIT:
	MOV AH,4CH
    INT 21H
CODES ENDS
    END START

5.8 把 AX 中存放的 16 位二进制数 K 看作是 8 个二进制的“四分之一字节”。试编写程序
要求数一下值为 3(即 11B)的四分之一字节数,并将该数(即 11B 的个数)在终端上显示出来

DATAS SEGMENT
    NUM DW 0 ;存放11的个数
    A DW 55 ;0000 0000 0011 0111
DATAS ENDS

STACKS SEGMENT
    DW 30H DUP(?)
    TOP LABEL WORD
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    MOV AX,STACKS
    MOV SS,AX
    LEA SP,TOP
    
	MOV CX,8
	MOV AX,A
L1: PUSH CX
	MOV CL,2
	ROL AX,CL ;注意移位操作
	MOV DX,AX
	AND DX,03H 
	;比较是否等于3
	CMP DX,03H ;直接比较即可,不用ADD DX,30H,取出来时已经是数字类型
	JNE NEXT
	INC NUM
	
NEXT:
	POP CX
	LOOP L1
	
PRINT:;结果不超过8
	MOV DX,NUM
	ADD DL,30H
	MOV AH,02H
	INT 21H
    ;结束
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

5.9 试编写一个汇编语言程序,要求从键盘接收一个四位的 16 进制数,并在终端上显示与
它等值的二进制数

要点:

  1. 输入的范围为0-9,a-f(在doxbos上不知道为什么不能采用大写)
  2. 16进制输入存入DX,每次输入存在AL中,然后先左移DX,再ADD DX,AX,注意要对AH清零,否则就要出错
  3. 二进制输出:即0或1的输出
  4. 还要注意在把数值存放在DX中时,有时候可能在使用INT 21H功能时,对DX,AX造成了变化,所以输入结束后要尽快保存NUM
DATAS SEGMENT
    NUM DW ?  
DATAS ENDS

STACKS SEGMENT
    DW 30H DUP(0)
    TOP LABEL WORD
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    MOV AX,STACKS
    MOV SS,AX
    LEA SP,TOP
    
    ;输入16进制的4位数
    MOV DX,0
    MOV AX,0
    MOV CX,4
L1: PUSH CX
	MOV AH,01H
	INT 21H
	CMP AL,'0' ;小于0说明非法
	JB L1
	CMP AL,'9' ;大于9转入判断是否为A-F
	JBE NEXT
L2: CMP AL,'a' ;用大写没办法正确检验
	JB L1
	CMP AL,'f'
	JA L1
	SUB AL,27H ;A-F
NEXT:
	SUB AL,30H ;说明输入的数值在0-9范围
L3: MOV CL,4
	AND AL,0FH ;仅保留低四位!!!
	SHL DX,CL ;把DX左移四位
	MOV AH,0 ;!!!!!!!!为什么要清零
	ADD DX,AX ;存放到DL中
	POP CX
	LOOP L1
	
	;读取输入的字符
L4:	MOV NUM,DX
	MOV BX,NUM
	
	MOV CX,16
	MOV AH,02H
	MOV DL,0AH
	INT 21H ;输出换行符,美化格式
	 
NEXT_2:
	PUSH CX
	ROL BX,1 ;循环左移1位
	MOV DX,BX 
	AND DX,01H ;取最低位,用二进制输出
	ADD DX,30H ;转化为字符类型
	MOV AH,02H
	INT 21H
	POP CX
	LOOP NEXT_2
	
    ;此处输入代码段代码
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值