单片机。用汇编语言编程。 设计一软件延时1s的子程序。设晶振频率为12MHz。

单片机。用汇编语言编程。 设计一软件延时1s的子程序。设晶振频率为12MHz。,第1张

delay1000ms:(HT46R65的单片机)(注意不要开启计时中断允许位)

mov a,10000111b (设置频率和记数方式)(上升记数还是下降记数)

mov tmr0c,a (tmr0c 计数器的控制寄存器)

mov a,low(65536-31250) (设置的频率就是1S上升31250)因此是DELAY1S

mov TMR0L,a (计数器的赋予初始值的低位寄存器)

mov a,high(65536-31250)

mov TMR0h,a(计数器的赋予初始值的高位寄存器)

set tmr0c4 (打开记数)

snz intc06 (是否有中断请求标志)(有就跳过)

jmp $-1 (退回一步)

clr tmr0c4 (关闭记数)

clr intc06 (清除中断标志)

ret

        CODE  SEGMENT

              ASSUME    CS:CODE

              ORG       100H

      START:  PUSH      CS

              POP       DS

              PUSH      CS

              POP       ES

              MOV       DI,0

              MOV       SI,0

              MOV       BX,10

     @MAIN1:  MOV       CX,BX

              CALL      FACT

              ADD       SI,AX

              ADC       DI,DX

              DEC       BX

              JNZ       @MAIN1

              

              MOV       AX,SI

              MOV       DX,DI

              CALL      DISPDXAX

              MOV       AH,4CH

              INT       21H

;=====================================

; cx中存放要求阶乘的数 

; 阶乘结果在dx、ax中 

        FACT  PROC      NEAR

              PUSH      BX

              PUSH      SI

              PUSH      DI

              PUSHF

              MOV       DX,0

              MOV       AX,1

     @FACT1:  MOV       BX,CX

              CALL      MULT

              LOOP      @FACT1

              POPF

              POP       DI

              POP       SI

              POP       BX

              RET

        FACT  ENDP

;========================================================

; 无符号乘法子程序 (mul指令只能实现16位乘16位,

;     本子程序实现32位乘16位--限定数的大小,结果仍为32位) 

; 被乘数放置于dx,ax 中, 乘数放置于 bx中 

; 结果放置于dx,ax中(dx为高16位,ax为低16位) 

        MULT  PROC      NEAR

              PUSH      CX

              PUSH      SI

              PUSH      DI

              PUSHF

              MOV       SI,0

              MOV       DI,0

              CMP       BX,0

              JE        @MULTEXIT

     @MULT1:  SHR       BX,1

              JNC       @MULT2

              ADD       SI,AX

              ADC       DI,DX

     @MULT2:  SHL       AX,1

              RCL       DX,1

              CMP       BX,0

              JNE       @MULT1

              MOV       DX,DI

              MOV       AX,SI

              POPF

              POP       DI

              POP       SI

              POP       CX

              RET

  @MULTEXIT:

              MOV       AX,0

              MOV       DX,0

              POPF

              POP       DI

              POP       SI

              POP       CX

              RET

        MULT  ENDP

;============================================

; 将要显示的32位无符号数置于dx、ax中 

    DISPDXAX  PROC      NEAR

              MOV       WORD PTR [Y],AX

              MOV       WORD PTR [Y+2],DX

       ; 以下将 Y (16进制)转为10进制串并输出

              MOV       AX,WORD PTR [Y]

              MOV       DX,WORD PTR [Y+2]

              MOV       BX,WORD PTR [Z]

              MOV       CX,WORD PTR [Z+2]

              MOV       WORD PTR N,0

        MM0:  INC       WORD PTR N

              SUB       AX,BX

              SBB       DX,CX

              JNC       MM0

              DEC       WORD PTR N

              ADD       AX,BX

              ADC       DX,CX

              MOV       WORD PTR[Y],AX

              MOV       WORD PTR[Y+2],DX

        MM1:  LEA       DI,CC

              ADD       DI,9

         M2:

              MOV       AX,WORD PTR [Y]

              MOV       DX,WORD PTR [Y+2]

              MOV       BX,10000

              DIV       BX

              PUSH      AX

              PUSH      DX

      ; 以下转换10进制的低4位

              POP       DX

              MOV       CX,4

              MOV       AX,DX

         M3:  MOV       DX,0

              MOV       BX,10

              DIV       BX

              ADD       DL,30H

              MOV       [DI],DL

              DEC       DI

              LOOP      M3

      ; 以下转换10进制的高万位

              POP       AX

              MOV       CX,1

         M4:  MOV       DX,0

              MOV       BX,10

              DIV       BX

              ADD       DL,30H

              MOV       [DI],DL

              DEC       DI

              LOOP      M4

              MOV       AX,WORD PTR N

              MOV       CX,5

         M5:  MOV       DX,0

              MOV       BX,10

              DIV       BX

              ADD       DL,30H

              MOV       [DI],DL

              DEC       DI

              LOOP      M5

      ; 输出换行回车

              LEA       DX,LFCR

              MOV       AH,9

              INT       21H

      ; 输出两数的和的10进制串

              LEA       DX,CC

              MOV       AH,9

              INT       21H

              RET

           Y  DD        

          CC  DB        10 DUP(' '),10,13,'$'

        LFCR  DB        10,13,'$'

           Z  DD        100000

           N  DW        0

    DISPDXAX  ENDP

        CODE  ENDS

              END       START

子程序中一般不能用JMP跳出,否则会造成地址混乱,因为调用子程序时会有堆栈 *** 作,将当前地址压栈,子程序返回时会出栈恢复地址,如果用JMP指令,那么就没有出栈 *** 作了,多调用几次,就可能造成堆栈溢出,从而程序就乱了。

汇编语言中主程序与子程序参数传递的方法有以下几种:

1寄存器法

寄存器法就是将入口参数和出口参数存放在约定的寄存器中。

优点:数据传递书读快、编程较方便、节省内存单元。

缺点:当传递参数过多时候,由于寄存器个数有限,及寄存器的频繁使用,将导致寄存器不足。

适用:参数较少的子程序

2。约定单元法:

约定单元法顾名思义是吧入口参数和出口参数都放在事先约定好的单元中

优点:不占用寄存器、参数个数任意、每个子程序要处理的数据和送出的结构都有独立的存储单元

缺点:但用一定数量的存储单元,增加编程中对变量定义的难度

3堆栈法

堆栈法是利用堆栈来传递参数的。

优点:参数不占用寄存器,和存储单元。参数存放在公共堆栈区,处理完后客恢复。参数个数一般不限

缺点:由于参数和子程序混杂在一起,存取参数时候必须小心计算它在堆栈中的位置。要注意断点的保存和恢复。

4地址表法

这种方法是把参数组成的一张参数表放在某个存储区中,然后只要主程序和子程序约定好这个存储区的首地址和存放的内容,在主程序中将参数传递给地址表,在子程序中根据地址表给定的参数就可以完成 *** 作。

DATAS SEGMENT

CIPHER db 'ASDSFASGDFFGFJJFGYZ'

LEN DW $-CIPHER

CHAR DB 26 DUP(0)

DATAS ENDS

CODES SEGMENT

ASSUME CS:CODES,DS:DATAS

START:

MOV AX,DATAS

MOV DS,AX

XOR AX,AX

MOV SI,OFFSET CIPHER

MOV CX,LEN

L1:

MOV BX,OFFSET CHAR

MOV AL,[SI]

SUB AL,41H

ADD BX,AX

ADD BYTE PTR [BX],1

INC SI

DEC CX

JNZ L1

MOV CH,26

MOV DL,41H

L3:

PUSH DX

MOV BL,DL

MOV DL,20H

MOV AH,2H

INT 21H

MOV DL,BL

MOV AH,2H

INT 21H

MOV DL,20H

MOV AH,2H

INT 21H

POP DX

INC DL

DEC CH

JNZ L3

MOV DL,0DH

MOV AH,2H

INT 21H

MOV DL,0AH

MOV AH,2H

INT 21H

MOV CH,26

MOV SI,OFFSET CHAR

MOV CL,4

L2:

mov bl,[si]

mov dl,bl

rol dl,cl

and dl,0fh

add dl,30h

mov ah,2h

int 21h

mov dl,bl

and dl,0fh

add dl,30h

mov ah,2h

int 21h

mov dl,20h

mov ah,2h

int 21h

inc SI

dec CH

jnz L2

MOV AH,4CH

INT 21H

CODES ENDS

END START

; 本程序在MASMPlus 12集成环境下通过编译,经过调试,运行正确。

Code Segment

Assume CS:Code,DS:Code

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

; 功能:显示指定地址(Str_Addr)的字符串

; 入口:

; Str_Addr=字符串地址(要求在数据段)

; 用法: Output Str_Addr

; 用法举例:Output PromptStr

Output MACRO Str_Addr

lea dx,Str_Addr

mov ah,9

int 21h

EndM

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

; 冒泡排序:对从MEM单元开始的N个8位无符号数降序排序

; 入口参数:ds:SI=数组地址,CX=数组元素个数

Bubbling Proc Near

push es

push si

push di

push cx

push ax

push ds

pop es

dec cx ;外循环次数

cld

@@Scanning: push cx ;入栈保存外循环次数

push si ;入栈保存数组地址

@@Compare: mov di,si ;当前数组元素地址赋给目的变址寄存器,以备交换之用

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

cmp al,[si] ;当前数组元素与相邻的下一个数组元素相比较

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

xchg al,[si] ;若小于,交换数组元素

stosb ;保存数值较小者

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

pop si ;数组地址出栈

pop cx ;外循环次数出栈

loop @@Scanning ;下一趟比较

pop ax

pop cx

pop di

pop si

pop es

ret

Bubbling EndP

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

MEM db 12,56,253,200,10,99,78,75,63,100

N equ $-MEM

Press_Key db 7,13,10,13,10,'The complated Press any key to exit$'

Start: push cs

pop ds

mov cx,N ;数组元素个数

lea si,MEM ;数组地址

call Bubbling

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

Exit_Proc: Output Press_Key ;提示 *** 作完成,按任意键结束程序

mov ah,1

int 21h

mov ah,4ch ;结束程序

int 21h

Code ENDS

END Start ;编译到此结束

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

Code Segment

Assume CS:Code,DS:Code

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

; 功能:显示指定地址(Str_Addr)的字符串

; 入口:

; Str_Addr=字符串地址(要求在数据段)

; 用法: Output Str_Addr

; 用法举例:Output PromptStr

Output MACRO Str_Addr

lea dx,Str_Addr

mov ah,9

int 21h

EndM

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

; 功能:输出回车换行

Output_CTLF proc Near

push ax

push dx

mov ah,02h

mov dl,0dh

int 21h

mov dl,0ah

int 21h

pop dx

pop ax

ret

Output_CTLF endp

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

; 功能:把AX中的二进制无符号数转换成显式的十进制ASCII码,并送显示屏显示

; 入口:AX=二进制数

; 出口:在当前光标位置显示转换后的ASCII码数字

Dec_ASCII Proc Near

push dx

push bx

push di

mov bx,10

lea di,@@Temp_Save[6]

mov byte ptr [di],'$'

dec di

cld

@@Divide: xor dx,dx

div bx

or dl,30h

mov [di],dl

dec di

test ax,0ffffh

jnz @@Divide

inc di

push di

pop dx

mov ah,9

int 21h

pop di

pop bx

pop dx

ret

@@Temp_Save db 7 dup()

Dec_ASCII EndP

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

; 功能:在N个字节数组中查找字符CHAR,并记录该字符出现的次数。

; 入口参数:

; si=一个N字节数的字符串TABLE首地址

; cx=字符串长度,N

; ah=要查找的字符

; 出口参数:bl=该字符出现的次数

Find_Chr Proc Near

@@Find_Chr: lodsb

cmp al,ah ;是指定的字符?

jnz $+4 ;不是

inc bl ;是,计数

loop Find_Chr ;判断下一个字符

ret

Find_Chr EndP

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

Prompt_Str db 'Please input a string: $' ;输入字符串提示信息

No_String db 'The string is null$' ;空字符串提示信息

Prompt_Chr db 'Please input a charactor: $' ;输入字符提示信息

Prompt_CNT db 'The specified charactor in th string TABLE: $' ;指定字符出现次数提示信息

Start: push cs

pop ds

push cs

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

cld

Input_Str: Output Prompt_Str ;提示输入字符串

lea dx,TABLE ;字符串缓冲区地址

mov ah,0ah

int 21h

call Output_CTLF ;输出一个回车、换行

lea si,TABLE[1] ;实际输入的字符串长度地址

lodsb ;读入这个长度N

test al,0ffh ;N=0?

jnz Read_Chr ;否,转去输入一个字符

Output No_String ;空字符串提示信息

jmp Input_Str ;重新输入字符串

Read_Chr: Output Prompt_Chr ;提示输入字符

mov ah,1 ;从键盘输入一个字符

int 21h

cmp al,1bh

jz Exit_Proc ;若按键为Esc,则结束程序

cmp al,20h ;控制及通讯字符?

jb Read_Chr ;重新输入字符

call Output_CTLF ;输出一个回车、换行

call Output_CTLF ;输出一个回车、换行

push ax

Output Prompt_CNT ;提示指定字符出现次数提示

pop ax

mov ah,al ;指定的字符送ah保存

lea si,TABLE[1] ;实际输入的字符串长度地址

lodsb ;读入这个长度N

mov cl,al

xor ch,ch ;N=cx

xor bl,bl ;计数器,计数指定字符在字符串中出现的次数

call Find_Chr ;在N个字节数组中查找字符CHAR,并记录该字符出现的次数

mov al,bl

xor ah,ah

call Dec_ASCII ;把AX中的二进制无符号数转换成显式的十进制ASCII码,并送显示屏显示

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

int 21h

TABLE db 255 ; 字符串缓冲区

Code ENDS

END Start ;编译到此结束

以上就是关于单片机。用汇编语言编程。 设计一软件延时1s的子程序。设晶振频率为12MHz。全部的内容,包括:单片机。用汇编语言编程。 设计一软件延时1s的子程序。设晶振频率为12MHz。、用汇编语言设计程序实现10!,并用调用子程序的方法实现1!+2!+3!+……+10!、汇编语言中,我设计了一个子程序,我想问一下在子程序中可以用jmp跳出该子程序吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存