题目:编写程序,将一个包含有20个有符号数据的数组ARRAYM分成两个数组:正数数组ARRAYP和负数数组ARRAYN。设数据均为8位。试分别统计负数个数,并计算正数之和。
详细讲解
前置内容回顾:
汇编语言(Assembly Language)习题:键盘输入一个字符串,试将其中的小写字母转换为大写字母,其它字符保持不变。
汇编语言(Assembly Language)习题:键盘输入任意一个字母,显示其前导字母、字母自身、后续字符共三个字母。
1.DATAS SEGMENT
DATAS SEGMENT
BUFF1 DB 'NAGATIVE NUMBER:$'
BUFF2 DB 'POSITIVE SUM:$'
BUFF3 db 0ah,0dh,'$'
NUM DB 2,5,6,-1,-4,20,10,-11,-12,10,-14,1,7,0,0,-6,-5,-4,-6,-1 ;我们要进行操作的数组
NEGA DB 20 DUP(?) ;negative 即负数 分别预留20个未赋初值的字节空间
POSI DB 20 DUP(?) ;positive 即正数
COUNTN DW 0
COUNTP DW 0
DATAS ENDS
这里总结一下:
?表达式
- 只定义变量,不赋初值。亦即只为变量申请存储空间而不赋初值。
- 如果这样定义变量的初值,那么汇编程序在处理数据定义伪指令时仅为变量分配空间,并不会为它设置初值。
- 程序执行时,这种变量的初值就是相应内存单元中原来所有的随机值。
带DUP的表达式
- 在表达式中使用重复数据操作符DUP,可以为连续的存储单元提供重复数据,其格式为:
N DUP(表达式) - 其中N为重复因子,只能取正整数,表示定义了N个重复数据存储单元,其类型由它前面的数据定义伪指令确定,而每个数据存储单元中的 初值由DUP后面圆括号中的表达式给定。
- 例如: BUF DB 100 DUP(0)
- 以上语句定义了以BUF为首址,大小为100个字节,初值为0的数据存储单元
2. CODES SEGMENT(1)
START: MOV AX,DATAS
MOV DS,AX
LEA SI,NEGA
LEA DI,POSI
LEA BX,NUM
MOV CX,20
CMP_: MOV AL,[BX] ;将NUM中每个数和0比较,不同情况跳转不同地方,
CMP AL,0
JZ ZERO
JG POSI_ ;思考一下为什么没有 JL NEGA_ 语句?
NEGA_: MOV [SI],AL
INC SI
INC BX
INC COUNTN
JMP LOP ;完成后继续下一个数字
POSI_: MOV [DI],AL
MOV AH,0
MOV AX,COUNTP ;因为COUNTP 是DB类型,所以必须ah先清零再进行mov,以防出错。
ADD AX,[DI] ;进行加法
MOV COUNTP,AX
INC DI
INC BX
JMP LOP
ZERO: INC BX
LOP: LOOP CMP_
有效地址送寄存器指令: LEA REG, SRC
执行操作: (REG) <- SRC
(2)比较两个无符号数,并根据比较的结果转移。
① JB(或 JNAE,或 JC)低于,或者不高于或等于,或进位位为 1 则转移。
② JNB(或JAE,或JNC)不低于,或者高于或等于,或进位位为 0则转移。
以上两种指令与(1)组指令中的⑨和⑩两种完全相同
③ JBE(或JNA)(jump if below or equal, or not(above)低于或等于,或不高于则转移。
格式:JBE(或JNA)OPR
测试条件:CF∨ZF=1
转移。④JNBE(或 JA)(jump if not below or equal, or above)不低于或等于,或高于则
格式:JNBE(或 JA)OPR
测试条件:CF∨ZF=0
(3)比较两个带符号数,并根据比较结果转移
① JL(或 JNGE)(jump if(less, or not greater or equal)小于,或者不大于或等于则转移。
格式:JL(或 JNGE)OPR
测试条件:SF∀OF=1
② JNL(或 JGE)(jump if not less,or greater or equal)不小于,或者大于或等于则转移。
格式:JNL(或 JGE)OPR
测试条件:SF∀OF=0
③JLE(或 JNG)(jump if less or equal,or not greater)小于或等于,或者不大于则转移。
格式:JLE(或 JNG)OPR
测试条件:(SF∀OF)∨ZF=1
④JNLE(或 JG)(jump if not less or equal,or greater)不小于或等于,或者大于则转移。
格式:JNLE(或 JG)OPR
测试条件:(SF∀OF)∨ZF=0
3. CODES SEGMENT(2)
输出结果
NEXT:
MOV DX,OFFSET BUFF1
MOV AH,9
INT 21H
MOV BX,COUNTN
CALL RESULT
mov dx,offset BUFF3
mov ah,9
int 21h
MOV DX,OFFSET BUFF2
MOV AH,9
INT 21H
MOV BX,COUNTP
CALL RESULT
MOV AH,4CH
INT 21H
完整代码
DATAS SEGMENT
BUFF1 DB 'NAGATIVE NUMBER:$'
BUFF2 DB 'POSITIVE SUM:$'
BUFF3 db 0ah,0dh,'$'
NUM DB 2,5,6,-1,-4,20,10,-11,-12,10,-14,1,7,0,0,-6,-5,-4,-6,-1
NEGA DB 20 DUP(?) ;negetive 即负数 分别预留20个未赋初值的字节空间
POSI DB 20 DUP(?) ;positive 即正数
COUNTN DW 0
COUNTP DW 0
DATAS ENDS
STACK SEGMENT PARA STACK
DW 20H DUP(0)
STACK ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACK
START: MOV AX,DATAS
MOV DS,AX
LEA SI,NEGA
LEA DI,POSI
LEA BX,NUM
MOV CX,20
CMP_: MOV AL,[BX]
CMP AL,0
JZ ZERO
JG POSI_
NEGA_: MOV [SI],AL
INC SI
INC BX
INC COUNTN
JMP LOP
POSI_: MOV [DI],AL
MOV AH,0
MOV AX,COUNTP
ADD AX,[DI]
MOV COUNTP,AX
INC DI
INC BX
JMP LOP
ZERO: INC BX
LOP: LOOP CMP_
NEXT:
MOV DX,OFFSET BUFF1
MOV AH,9
INT 21H
MOV BX,COUNTN
CALL RESULT
mov dx,offset BUFF3
mov ah,9
int 21h
MOV DX,OFFSET BUFF2
MOV AH,9
INT 21H
MOV BX,COUNTP
CALL RESULT
MOV AH,4CH
INT 21H
result proc near ;子程序功能:输出十进制的结果
mov cx,10000d
call div_
mov cx,1000d
call div_
mov cx,100d
call div_
mov cx,10d
call div_
mov cx,1d
call div_
ret
result endp
div_ proc near
mov ax, bx
mov dx, 0
div cx
mov bx, dx
mov dl, al
add dl, 30h
mov ah, 2
int 21h
ret
div_ endp
CODES ENDS
END START