汇编语言实验设计分支程序设计判断几个数据是正数还是负数

汇编语言实验设计分支程序设计判断几个数据是正数还是负数,第1张

比如:

buf    db 1,2,6,-6,-3,8,9

num    db $-buf

        mov cl,num

        xor ch,ch

        lea si,buf

        cld

@0:

        lodsb

        cmp al,0

        jl @1

        mov ah,2

        mov dl,'+'

        int 21h

        jmp @2

@1:

        mov ah,2

        mov dl,'-'

        int 21h

@2:

        loop @0

1.编写一个程序实现:在BUF开始的存储区中存放30个带符号数,试统计其正数、负数和零的个数,并将统计的个数分别放到PLUS、NEGATIVE、ZERO单元中。

; 本程序通过编译,运行正确

Code Segment

Assume CS:Code,DS:Code

BUF db 23,-69,0,35,46,0,57,68,0,79,81,98,-43,251,21,15,-69,0,58,159,-27,-89,65,76,85,123,0,253,193,121

Elements equ ($-BUF)/Type BUF ;元素个数

Plus db 0 ;正数计数

Negative db 0 ;负数计数

Zero db 0 ;零计数

Start: push cs

pop ds

push cs

pop es ;使数据段、附加段与代码段同段

cld

lea si,BUF ;取数据地址

mov cx,Elements ;元素个数

Statics: cmp byte ptr [si],0 ;是否0?

jnz $+8 ;不是

inc Zero ;是,0计数

jmp Next_One

test byte ptr [si],80h ;是否正数?

jnz $+8 ;不是

inc Plus ;是,正数计数

jmp $+6

inc Negative ;负数计数

Next_One:inc si ;si增1,判断下一个元素

loop Statics

Exit_Proc: mov ah,4ch ;结束程序

int 21h

Code ENDS

END Start ;编译到此结束

2.若内存BUF开始的单元中存放10个无序的有符号数,试用冒泡法将它们升序排列。

; 冒泡法排序

Code Segment

Assume CS:Code,DS:Code

; -----------------------------------------

; 定义常量

Yes EQU 1

No EQU 0

On EQU 1

Off EQU 0

; -----------------------------------------

; 定义结构类型

Bubb_Para Struc ; 冒泡排序法参数表

Carry DB No ; 是否带符号。Yes:有符号数;No:无符号数

Sort DB No ; 升序/降序。Yes:升序;No:降序

Yes_No DB 73h,76h,7dh,7eh

Load DB 0ach,0adh

Comp DB 3ah,3bh

Exchange DB 86h,87h

Store DB 0aah,0abh

Bubb_Para EndS

; -----------------------------------------

; 功能:按要求对数组元素排序,能够对字节元素、字元素进行无符号数、有符号数的升序、降序排序。

; 子程序原型:对字节元素进行无符号升序排序。

Bubbling Proc Near

PUSH AX

PUSH BX

PUSH CX

PUSH SI

PUSH DI

; ------------------根据排序参数,修改排序指令

LEA SI,Parameters

LEA DI,@@Compare

MOV AL,TYPE BUF

DEC AL

PUSH AX

LEA BX,[SILoad]

XLAT

MOV [DI][2],AL

POP AX

PUSH AX

LEA BX,[SIComp]

XLAT

MOV [DI][3],AL

POP AX

PUSH AX

LEA BX,[SIExchange]

XLAT

MOV [DI][7],AL

POP AX

LEA BX,[SIStore]

XLAT

MOV [DI][9],AL

MOV AL,[SICarry]

SHL AL,1

OR AL,[SISort]

XOR AH,AH

LEA BX,[SIYes_No]

XLAT

MOV [DI][5],AL

; ------------------按要求排序

MOV CX,Elements ;外循环次数

@@Scanning: PUSH CX ;入栈保存外循环次数

LEA SI,BUF ;数组首地址装入源变址寄存器

@@Compare: PUSH SI

POP DI ;当前数组元素地址赋给目的变址寄存器,以备交换之用

LODSB ;将当前数组元素读入累加器

CMP AL,[SI] ;当前数组元素与相邻的下一个数组元素相比较

JBE @@NextOne ;若小于或等于,不作数据交换,处理下一个数组元素

XCHG AL,[SI] ;若大于,交换数组元素

STOSB ;保存数值较小者

@@NextOne: LOOP @@Compare ;处理下一个数组元素

POP CX ;外循环次数出栈

LOOP @@Scanning ;下一趟比较

; ------------------

POP DI

POP SI

POP CX

POP BX

POP AX

RET

Bubbling EndP

BUF DB -112,56,72,98,32,251,97,63,123,21 ;需要排序的数据

Elements EQU ($-BUF)/Type BUF-1 ; 外循环次数

Parameters Bubb_Para <Yes,Yes>

Start: push cs

pop ds

push cs

pop es ;使数据段、附加段与代码段同段

call Bubbling ;对BUF中的元素按无符号数、升序排序

Exit_Proc: mov ah,4ch ;结束程序

int 21h

Code ENDS

END Start ;编译到此结束

MODE_RG EQU  40H ;模式选择

 MODE2 EQU  60H ;MODE值

 MODE3 EQU  61H

 MODE4 EQU  62H

 MODE5 EQU  63H

 MODE6 EQU  64H

 MODE1 EQU  65H

 HOUR    EQU  41H ;小时缓冲区

 MIN     EQU  42H ;分钟缓冲区

 SEC     EQU  43H ;秒缓冲区

 TEMP EQU  4AH

 ;闹钟缓冲区

 H_ALARM EQU  6AH ;闹钟缓冲区

 M_ALARM EQU  6BH

 S_ALARM EQU  6CH

 F_ALARM EQU  6DH

 ;秒表缓冲区

 M_SEC EQU  76H

 S_SEC EQU  77H

 ;LED送显示临时变量

 LED0 EQU  51H

 LED1 EQU  52H

 LED2       EQU  53H

 LED3 EQU  54H

 MODE_KEY   EQU  P34

 UP_KEY EQU  P33

 DOWN_KEY EQU  P35

 BUF EQU  49H

ORG 0000H

LJMP MAIN

ORG 000BH

LJMP INT_0

ORG 001BH

LJMP INT_1

ORG 0080H

MAIN: MOV SP,#2FH  ;堆栈初始化

MOV MODE_RG,#0  ;MODE_RG寄存器值初始化

MOV LED0,#0FEH  ;初始化LED

MOV LED1,#0FDH

MOV LED2,#0FBH

MOV LED3,#0F7H

MOV MODE1,#1

MOV MODE2,#2

MOV MODE3,#3

MOV MODE4,#4

MOV MODE5,#5

MOV MODE6,#6

MOV F_ALARM,#0  ;错误2:一开始用 CLR F_ALARM,这导致在后面的时候JZ F_ALARM 运行错误,

MOV BUF,#0 ;在于 JZ 指令是对累加器A全为0或者全为1进行判断,CLR只能对一位 *** 作

MOV TMOD,#11H  ;定时器初始化:定时器0,方式1,定时器1,方式1

MOV IP,#00001000B  ;定时器1优先级高

MOV TH0,#3CH  ;定时50MS

MOV TL0,#0B1H

MOV TH1,#0D8H  ;定时10MS

MOV TL1,#0F0H

SETB EA

SETB ET0

SETB ET1

SETB TR0             ;启动定时器

        MOV HOUR,#0      ;for test

MOV MIN,#0

MOV SEC,#0  ;定时器计数器,50MS中断一次,200次则刚好1S

MOV M_SEC,#0

MOV S_SEC,#0

MOV H_ALARM,#0

MOV M_ALARM,#0

MAIN1: LCALL DISPLAY12

LCALL DISPLAY34

;CLR P14    TEST

JNB MODE_KEY,KEY_SCAN

MOV A,MODE_RG

CJNE A,MODE6,Y1   ;MODE6  秒表

JNB DOWN_KEY,DEALDOWN    ;判断秒表开关

JNB UP_KEY,DEALUP

Y1: MOV A,F_ALARM   ;判断闹钟

JNZ ALARM

LJMP MAIN1

;-----------------------------------秒表开关程序---------------------------

DEALDOWN: LCALL DELY10MS

JB DOWN_KEY,MAIN1

H1: JNB DOWN_KEY,H1

CPL TR1

LJMP MAIN1

DEALUP: LCALL DELY10MS

JB UP_KEY,MAIN1

H2: JNB UP_KEY,H2

MOV M_SEC,#0

MOV S_SEC,#0

CLR TR1

LJMP MAIN1

;-----------------------------------闹钟扫描程序---------------------------

ALARM: MOV A,H_ALARM

CPL P12

CJNE A,HOUR,EXIT3

MOV A,M_ALARM

CJNE A,MIN,EXIT3

LJMP STARTALARM

EXIT3: SETB P36

LJMP MAIN1

STARTALARM: CPL P36

JNB DOWN_KEY,OFFALARM

LJMP S1

OFFALARM: LCALL DELY10MS

JB DOWN_KEY,MAIN1

S2: JNB DOWN_KEY,S2

MOV F_ALARM,#0

SETB P36

LJMP MAIN1

S1: LCALL DELAY

LJMP MAIN1

;-----------------------------------键盘扫描程序---------------------------

KEY_SCAN: LCALL DELY10MS

JB MODE_KEY,MAIN1

INC MODE_RG

;SETB P14    测试

K1: JNB MODE_KEY,K1  ;按键直到用户松开按键

K2: MOV A,MODE_RG

CJNE A,#0,DEALMODE  ;不是在正常显示模式下则跳转到模式处理程序

LJMP MAIN1  ;返回主程序

;模式处理程序部分

DEALMODE: MOV TEMP,#0  ;凡转入MODE处理,则首先清除TEMP

MOV A,MODE_RG  ;有MODE_RG值不为5、0

CJNE A,MODE2,M0  ;判断MODE_RG值,不为1跳转

LJMP H_GLINT  ;模式1,小时位闪烁

M0: CJNE A,MODE3,M1  ;不是模式2,跳转

LJMP M_GLINT  ;模式2,分钟位闪烁

M1: CJNE A,MODE4,M2  ;不是模式3,跳转

LJMP H_GLINT

M2:   CJNE A,MODE5,M3

LJMP M_GLINT

M3: CJNE A,MODE6,M4

MOV M_SEC,#0

MOV S_SEC,#0

LJMP MAIN1

M4: CJNE A,MODE1,M5

;CLR TR1

LJMP MAIN1

M5: MOV MODE_RG,#0

LJMP MAIN1

;MODE为1,3,小时位闪烁

//MOV TEMP,HOUR  ;将TEMP赋值,防止在加的时候是在随机值的基础上增加

H_GLINT: ;CPL P10

MOV R0,#28

MOV R1,#28

K4: LCALL DISPLAY12  ;分开显示

LCALL DISPLAY34

E1: JNB MODE_KEY,K21  ;检测是否有按键按下,有按下则跳转到分钟位闪烁

JB UP_KEY,E9  ;判断加位有无按键按下

LJMP UP

E9: DJNZ R0,K4

K6: LCALL DISPLAY34

JNB MODE_KEY,K21  ;检测是否有按键按下,有按下则跳转延时后进行模式判断

LJMP G1

K21: LCALL DELY10MS  ;延时后确定有MODE按键按下,将

JB MODE_KEY,H_GLINT

W: JNB MODE_KEY,W

INC MODE_RG

CPL P14

LJMP DEALMODE  ;确定有按下,MODE+1后返回MODE处理程序

JNB UP_KEY,UP  ;判断加位有无按键按下

G1: DJNZ R1,K6

LJMP H_GLINT  ;调用完毕返回,实现闪烁

K3: LJMP MAIN1  ;可省略

;MODE为2,4,分钟位闪烁

M_GLINT: MOV R0,#28

MOV R1,#28

K23: CPL P17

LCALL DISPLAY12

LCALL DISPLAY34

JNB MODE_KEY,KK  ;跳转,确定是否有按键按下

JNB UP_KEY,UP  ;判断加位有无按键按下

MOV A,MODE_RG

CJNE A,MODE3,E2  ;在MODE5的情况下要判断闹钟确认键有没按下

LJMP E5

E2: JNB DOWN_KEY,F2

LJMP E5

F2: LJMP ONALARM2

E5: DJNZ R0,K23

K24: LCALL DISPLAY12

JNB MODE_KEY,KK  ;检测是否有按键按下,有按下则跳转

JNB UP_KEY,UP  ;判断加位有无按键按下

MOV A,MODE_RG  ;扫描闹钟确认键

CJNE A,MODE3,E7  ;在MODE5的情况下要判断闹钟确认键有没按下

LJMP G2

E7: JB DOWN_KEY,E8

CPL P13

LJMP ONALARM2

E8: LJMP G2

KK: LCALL DELY10MS  ;去抖

JB MODE_KEY,M_GLINT

W1: JNB MODE_KEY,W1

INC MODE_RG

CPL P14

LJMP DEALMODE  ;确定有按下,MODE+1后返回MODE处理程序

G2: DJNZ R1,K24

LJMP M_GLINT

;位加,处理程序

;小时调整

UP: MOV R1,#20

UP11: INC TEMP

UP12: MOV A,MODE_RG  ;判断此时的MODE,根据MODE将临时变量给对应的赋值

CJNE A,MODE2,AA0  ;不是在MODE2的情况下跳转

MOV A,TEMP

CJNE A,#24,A_UP1

MOV TEMP,#0

A_UP1: MOV HOUR,TEMP  ;为MODE2,将临时变量赋给小时位

LJMP UP15

AA0: CJNE A,MODE4,UP13    //UP13为分钟调整入口

MOV A,TEMP

CJNE A,#24,A_UP

MOV TEMP,#0

A_UP: MOV H_ALARM,TEMP   ;模式3,将临时变量赋给闹钟的小时位

LJMP UP15   ;UP15为显示入口

;分钟调整入口

UP13: MOV A,MODE_RG

CJNE A,MODE3,UP14  ;不是模式2,跳转

MOV A,TEMP

CJNE A,#60,DISOVER2

MOV TEMP,#0

DISOVER2: MOV MIN,TEMP

LJMP UP15

UP14: MOV A,TEMP  ;上面判断不是模式2,则必然是模式4

CJNE A,#60,DISOVER3

MOV TEMP,#0

DISOVER3: MOV M_ALARM,TEMP

LJMP UP15

UP15: LCALL DISPLAY12

LCALL DISPLAY34

DJNZ R1,UP01

MOV R1,#1   ;

JNB UP_KEY,UP11

UP01: JNB UP_KEY,UP12

UP16: MOV A,MODE_RG   ;松开键以后按照模式判断该返回哪种状态,不能返回DEALMODE函数

CJNE A,MODE2,UP17

LJMP H_GLINT

UP17: CJNE A,MODE3,UP18

MOV SEC,#0   ;每次设置完时间后将秒钟位置零保证时间准确

LJMP M_GLINT

UP18: CJNE A,MODE4,UP19

LJMP H_GLINT

UP19: CJNE A,MODE5,UP20

LJMP M_GLINT

UP20: LJMP MAIN1

ONALARM2: LCALL DELY10MS  ;延时10MS,去抖

JB DOWN_KEY,B2  ;抖动所致,返回分钟位闪烁

LJMP K42

B2: LJMP M_GLINT

K42: JNB DOWN_KEY,K42

MOV F_ALARM,#0FFH

MOV MODE_RG,#0

LJMP MAIN1

;---------------------------------------中断程序入口---------------------

;时间中断0

;错误1:中断程序EXIT处用了MAIN1,导致一直处于中断状态

INT_0: PUSH ACC

PUSH PSW

MOV TH0,#3CH

MOV TL0,#0B1H

INC BUF

MOV A,BUF

CJNE A,#20,EXIT

TIME: MOV BUF,#0

INC SEC

MOV A,SEC

CJNE A,#60,EXIT

MOV SEC,#00H

INC MIN

MOV A,MIN

CJNE A,#60,EXIT

MOV MIN,#00H

INC HOUR

MOV A,HOUR

CJNE A,#24,EXIT

MOV HOUR,#0

RETI

EXIT:  POP PSW

   POP ACC

  RETI

;时间中断1

INT_1:  MOV TH1,#0D8H  ;定时10MS

MOV TL1,#0F0H

INC S_SEC

MOV A,S_SEC

CJNE A,#100,EXIT4

MOV S_SEC,#0

INC M_SEC

MOV A,M_SEC

CJNE A,#100,EXIT4

MOV M_SEC,#0

EXIT4: RETI

;---------------------------------------显示-----------------------------

DISPLAY12: MOV A,MODE_RG   ;判断模式,决定是显示闹钟时间还是显示当前时间

CJNE A,MODE4,DIS0   ;模式四,显示闹钟

LJMP DIS01   ;MODE4

DIS0: CJNE A,MODE5,DIS20

DIS01: MOV R7,H_ALARM   ;闹钟模式

LJMP DIS2

DIS20: CJNE A,MODE6,DIS21

MOV R7,M_SEC   ;秒表模式,显示秒表高位

LJMP DIS2

DIS21: CJNE A,MODE1,DIS1

LJMP DIS22

DIS22: MOV R7,MIN

LJMP DIS2

DIS1: MOV R7,HOUR   ;DISPLAY12显示高位

DIS2: LCALL BCTD   ;判断完毕,调用显示

;将秒、分 分别转码,放到R4,R3

MOV A,R4

MOV R3,A

LCALL DIVIDE

MOV DPTR,#NUMTAB

MOV P2,#0FH

MOV P2,LED0

MOV A,45H  ;从拆字的出口获取值

MOVC A,@A+DPTR

MOV P0,A

LCALL DELY10MS

MOV P2,LED1

MOV A,46H

MOVC A,@A+DPTR

MOV P0,A

LCALL DELY10MS

RET

DISPLAY34: MOV A,MODE_RG   ;判断模式,决定是显示闹钟时间还是显示当前时间

CJNE A,MODE4,DIS31

LJMP DIS32

DIS31: CJNE A,MODE5,DIS35

DIS32: MOV R7,M_ALARM

LJMP DIS34

DIS35: CJNE A,MODE6,DIS41

MOV R7,S_SEC   ;秒表模式,显示秒表低位

LJMP DIS34

DIS41: CJNE A,MODE1,DIS33

MOV R7,SEC

LJMP DIS34

DIS33: MOV R7,MIN  ;DISPLAY34显示低位

DIS34: LCALL BCTD

MOV A,R4

MOV R3,A

LCALL DIVIDE

MOV P2,LED2

MOV A,47H

MOVC A,@A+DPTR

MOV P0,A

LCALL DELY10MS

MOV P2,LED3

MOV A,48H

MOVC A,@A+DPTR

MOV P0,A

LCALL DELY10MS

SETB P23

RET

;--------------------二翻十:入口:R6R7 出口:R2R3R4----------------------

BCTD: MOV R5,#16

CLR A

MOV R2,A

MOV R3,A

MOV R4,A

LOOP: CLR C

MOV A,R7

RLC A

MOV R7,A

MOV A,R6

RLC A

MOV R6,A

MOV A,R4

ADDC A,R4

DA A

MOV R4,A

MOV A,R3

ADDC A,R3

DA A

MOV R3,A

MOV A,R2

ADDC A,R2

DA A

MOV R2,A

DJNZ R5,LOOP

RET

;-----------------------拆字:入口:R3R4 出口:45H46H47H48H------------------

DIVIDE: MOV A,R3

ANL A,#0FH

MOV 46H,A

MOV A,R3

ANL A,#0F0H

SWAP A

MOV 45H,A      ;时拆字 45H放时高位,46H放十低位

MOV A,R4

ANL A,#0FH

MOV 48H,A

MOV A,R4

ANL A,#0F0H

SWAP A

MOV 47H,A      ;分拆字 47H放分高位,48H放分低位

RET

;------------------------------------延时----------------------------------

DELY10MS:   MOV R6,#10

D1:         MOV R7,#248

DJNZ R7,$

DJNZ R6,D1

RET

DELAY: MOV 74H,#2 ;延时子程序,12M晶振延时1002秒

L3:  MOV 72H ,#10

L1:  MOV 73H ,#249

L2:  DJNZ 73H ,L2

LCALL DISPLAY12

LCALL DISPLAY34

JNB DOWN_KEY,OFFALARM1

LJMP S3

OFFALARM1: LCALL DELY10MS

JB DOWN_KEY,S3

S4: JNB DOWN_KEY,S4

MOV F_ALARM,#0

SETB P36

LJMP MAIN1

S3: DJNZ 72H ,L1

DJNZ 74H ,L3

RET

NUMTAB:     DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EH  ;码表

END

以上就是关于汇编语言实验设计分支程序设计判断几个数据是正数还是负数全部的内容,包括:汇编语言实验设计分支程序设计判断几个数据是正数还是负数、汇编语言程序设计题求高手、求单片机课程设计实验 用汇编语言,基于51单片机的定时闹钟等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9286013.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存