電工學習網

 找回密碼
 立即注冊

循環程序的設計

2015-3-22 09:31| 編輯:電工學習網| 查看: 4388| 評論: 0

摘要: 循環程序可以有兩種結構形式,如圖所示。一種是DO_WHILE結構形式;另一種是DO_UNTIL結構形式。 例5.1  設內存BUFF開始的單元中依次存放著30個8位無符號數,求它們的和并放在SUM單元中,試編寫程序。 分析:這是 ...

    循環程序可以有兩種結構形式,如圖所示。一種是DO_WHILE結構形式;另一種是DO_UNTIL結構形式。

    例5.1  設內存BUFF開始的單元中依次存放著30個8位無符號數,求它們的和并放在SUM單元中,試編寫程序。

    分析:這是一個求累加的程序。程序如下:

    MOV  SI,BUFF  ;設地址指針

    MOV CX,30    ;設計數初值

    XOR AX,AX   ;設累加器初值

    AGAIN: ADD AL,[SI]

    ADC AH,0

    INC  SI

    DEC CX

    JNZ  AGAIN     ;循環累加

    MOV SUM,AX

    例5.2  在給定個數的16位數串中,找出大于零、等于零和小于零的個數,并緊跟著原串存放。

    分析:這是一個統計問題,須設定三個計數器分別統計三種情況下的結果。程序如下:

    DATA SEGMENT

    BUFF DW  X1,X2,X3,……,Xn

    COUNT  EQU  $-BUFF   ;此時,COUNT的值為BUFF所占的字節數

    PLUSE  DB   ?

    ZERO   DB   ?

    MINUS DB   ?

    DATA ENDS

    CODE SEGMENT

    ASSUME CS:CODE,DS:DATA

    ASSUME ES:DATA,SS:STACK

    BEGIN: MOV AX,DATA

    MOV DS,AX

    MOV CX,COUNT

    SHR CX,1         ;相當于除2,正好為BUFF中的數據個數

    MOV DX,0          ;設定計數器初值

    MOV AX,0          ;設定計數器初值

    LEA  BX,BUFF

    AGAIN:   CMP  WORD PTR[BX],0

    JAE  PLU        ;大于等于0,則轉PIU

    INC  AH         ;<0,則統計

    JMP  NEXT

    PLU:     JZ  ZER         ;=0,則轉ZER

    INC  DL          ;>0,則統計

    JMP  NEXT

    ZER:  INC  DH          ;=0,則統計

    NEXT:  INC  BX

    INC  BX

    LOOP AGAIN

    MOV PLUS,DL

    MOV ZERO,DH

    MOV MINUS,AH

    MOV AX,4C00H

    INT  21H

    CODE  ENDS

    END BEGIN

    例5.3 在ADDR單元中存放著16位數Y的地址,試編寫一程序,把Y中1的個數存入COUNT單元中。

    分析:這是一個循環統計的工作。采用DO—WHILE結構,做16次循環,每次將最高位移入CF中進行測試,先判斷結果是否為0,若為0,則結束;否則統計計數后循環重復。

    程序如下:

    DATA SEGMENT

    ADDR DW  NUMBER

    NUMBER DW  Y

    COUNT  DW  ?

    DATA  ENDS

    PROGRAM SEGMENT

    MAIN  PROC FAR

    ASSUME CS:PROGRAM,DS:DATA

    START: PUSH DS

    MOV AX,0

    PUSH AX

    MOV AX,DATA

    MOV DS,AX

    MOV CX,0         ;計數器初值=0

    MOV BX,ADDR

    MOV AX,[BX]       ;取Y送AX

    REPEAT: TEST AX,0FFFFH    ;檢測是否為全0

    JZ  EXIT           ;是,則轉EXIT

    JNS  SHIFT          ;最高位是0,則轉SHIFT

    INC  CX             ;最高位是1,則統計計數

    SHIFT:  SHL  AX,1   ;處理下一位

    JMP  REPEAT

    EXIT:  MOV COUNT,CX

    RET

    MAIN  ENDP

    PROGRAM ENDS

    END START

    在實際應用中,有些問題較復雜,一重循環不夠,必須使用多重循環實現,這些循環是一層套一層的,通常稱為循環嵌套。

    例5.4 在DS所決定的數據段,從偏移地址BUFFER開始順序存放100個無符號16位數,現要編寫程序將這100個字數據從大到小排序。

    分析:排序的方法有很多,在這里,我們采用冒泡法。

    程序如下:

    LEA  DI,BUFFER   ;DI作為指針,指向要排序的數據

    MOV BL,99         ;循環控制初值

    NEXT0:MOV SI,DI

    MOV CL,BL

    NEXT3:MOV AX,[SI]        ;取一個數

    ADD SI,2

    CMP AX,[SI]        ;與下一個數進行比較

    JNC  NEXT5      ;大于等于時轉移

    MOV DX,[SI]        ;否則,兩數交換

    MOV [SI-2],DX

    MOV [SI],AX

    NEXT5:DEC CL             ;控制進行交換的次數

    JNZ  NEXT3

    DEC BL             ;修改交換的次數

    JNZ  NEXT0

    HLT

    例5.5  試編制一個程序,把BX寄存器中的二進制數以十六進制的形式顯示在屏幕上。

    解析:根據題目要求應將BX中的內容從左到右每4位一組顯示出來,共顯示4個十六進制數位。如果顯示的數位是0~9,則把4位二進制數加上30H,轉換成相應的ASCII碼30H~39H;如果是A~F,則應加上37H(30H+7),轉換成ASCII碼41H~46H。顯示字符可以使用DOS功能調用來實現。下圖是程序框圖。

    

    以binihex.asm為文件名,建立源程序如下:

    ; binihex.Asm

    prognam segment           ; 定義代碼段

    main proc far

    assume cs:prognam 

    start:              ; 程序從此處開始執行 

    ; 為正常返回DOS而設置堆棧

    push    ds 

    sub     ax,ax 

    push    ax 

    ; 下面是程序的主要部分

    mov    ch,4       ; 4組二進制數

    rotate:

    mov    cl,4      ; 每組4個二進制位

    rol    bx,cl      ; 把bx循環左移4位

    mov    al,bl      ; 暫存bl到al中

    and    al,0fh      ; 僅保留al的低4位

    add    al,30h     ; 轉換成ASCII碼

    cmp    al,3ah     ; 要顯示的數大于9 ?

    jl     printit     ; 如果數在0~9之間則顯示

    add    al,7h      ; 數在A~F之間則調整

    printit:

    mov    dl,al      ; 把要顯示字符的ASCII碼送dl

    mov    ah,2       ; 功能號2送ah

    int    21h       ; DOS功能調用

    dec    ch        ; (ch)-1

    jnz    rotate      ; 4組都處理完?否,循環處理下一組

    ret            ; 返回DOS

    main   endp            ; 主程序main結束

    prognam  ends            ; 代碼段結束

    end    start      ; 結束匯編

    例5.6 從鍵盤接收十進制數并存入 BX

    prognam segment

    main proc far

    assume cs:prognam 

    start:

    push ds

    sub  ax,ax

    push ax

    mov   bx, 0

    newchar:

    mov   ah, 1  ;鍵盤輸入

    int   21h

    sub   al, 30h

    jl   exit  ;<0退出

    cmp   al, 9

    jg   exit  ;>9退出

    cbw

    

    例5.7 從鍵盤接收十六進制數并存入 BX

    

    code  segment 

    assume   cs:code, ds:data 

    

    start:

    mov ax,4c00h

    int 21h      ; 返回DOS

    code  ends

    end  start

    

    例5.8 將正數N插入一個已整序的字數組的正確位置。該數組的首地址和末地址分別為ARRAY_HEAD和ARRAY_END,其中所有數均為正數且已按遞增的次序排列。

    

    ; 定義數據段

    datarea segment

    x    dw  ?

    array_head  dw  23,37,49,52,65,78,99

    array_end  dw  105

    n   dw  32 

    datarea ends

    ; 定義代碼段

    prognam segment

    main  proc  far    ; 主程序部分 assume cs:prognam,ds:datarea

    start:         ; 程序從此處開始執行

    push  ds

    sub  ax,ax 

    push  ax

    mov  ax,datarea

    mov  ds,ax

    ; 程序的主要部分

    mov  ax,n

    mov  array_head-2,0ffffh  ; -1送array_head-2單元

    mov  si,0

    compare:

    cmp  array_end[si],ax

    jle  insert

    mov  bx,array_end[si]

    mov  array_end[si+2],bx

    sub  si,2

    jmp  short compare

    insert:

    mov  array_end[si+2],ax

    ret

    main  endp      ; 主程序main結束

    prognam ends

    end  start

    例5.9設有數組X (,…,) 和Y (,…,) ,編程計算數組Z (,…,) ,其中:

    

    

    

    ; 定義數據段

    datarea segment 

    x   dw  x1,x2,x3,x4,x5,x6.x7,x8,x9,x10

    y    dw  y1,y2,y3,y4,y5,y6,y7,y8,y9,y10

    z    dw  z1,z2,z3,z4,z5,z6,z7,z8,z9,z10

    logic_rule dw  00dch

    datarea ends

    ; 定義代碼段

    prognam segment

    main  proc  far

    assume cs:prognam,ds:datarea

    start: 

    push  ds 

    sub  ax, ax 

    push  ax 

    mov  ax, datarea 

    mov  ds, ax 

    mov  bx, 0

    mov  cx, 10

    mov  dx, logic_rule

    next: 

    mov  ax, x[bx]

    shr  dx, 1

    jc  subtract

    add  ax, y[bx]

    jmp  short result

    subtract:

    sub  ax, y[bx]

    result:

    mov  z[bx], ax

    add  bx, 2

    loop  next

    

    ret

    main  endp 

    prognam  ends

    end  start

    這種設置邏輯尺的方法是很常用的。例如,在矩陣運算中,為了跳過操作數為0的計算,經常采用這種方法。又如,把一組數據存入存儲器時,如果其中數值為0的元素很多,也可用這種方法設立一個每位表示一個下標的邏輯尺(這樣的邏輯尺可能占有幾個字,由數組的長度確定。),0元素就可不占有存儲單元了。每個標志只占一位,如果要表示的特征數更多,則每個標志可占有幾位,而在處理方法上是完全相同的。設立標志位的方法除了如邏輯尺那樣可靜態地預置外,還可以在程序中動態地修改標志位的值,以達到控制的目的,下例將說明這種方法。

    例5.10 試編制一程序:從鍵盤輸入一行字符,要求第一個鍵入的字符必須是空格符,如不是,則退出程序;如是,則開始接收鍵入的字符并順序存放在首地址為BUFFER的緩沖區中(空格符不存入),直到接收到第二個空格符時退出程序。

    這一程序要求接收的字符從空格符開始又以空格符結束,因此程序中必須區分所接收的字符是否是第一個字符。為此,設立作為標志的存儲單元FLAG。一開始將其置為0,接收第一個字符后可將其置1。整個程序的框圖如圖所示。

    

    ;定義數據段

    datarea  segment

    buffer db 80 dup(?)

    flag db ?

    datarea  ends

    ;定義代碼段

    prognam  segment 

    main proc far

    assume cs:prognam,ds:datarea

    start:

    push ds

    sub  ax,ax

    push ax

    mov  ax,datarea

    mov  ds,ax

    lea  bx,buffer

    mov  flag,0

    next: 

    mov  ah,01

    int  21h

    test flag,01h

    jnz/jne  follow

    cmp  al,20h

    jnz/jne  exit

    mov  flag,1

    jmp  next

    follow: 

    cmp  al,20h

    jz/je  exit

    mov  [bx],al

    inc  bx

    jmp  next

    exit: 

    ret 

    main  endp 

    prognam ends 

    end  start 

    

    例5.11 有一個首地址為A的N字數組,請編制程序使該數組中的數按照從小到大的次序整序。

    解析:這里采用起泡排序算法實現數組整序。從第一個數開始依次對相鄰兩個數Ki和Ki+1進行比較,若Ki≤Ki+1,Ki的位置不動,Ki+1繼續和Ki+2比較;若Ki>Ki+1,則兩者交換位置,Ki+1(交換前的Ki)繼續和Ki+2比較。

    (氣泡算法,多重循環)   32,85,16,15, 8

    

    ; 定義數據段

    dseg  segment

    n equ  5     ; 數組中數的個數

    a dw  n dup(?)

    dseg   ends

    ; 定義代碼段

    cseg  segment

    main  proc  far

    assume cs:cseg, ds:dseg

    start:

    mov  ax,dseg

    mov  ds,ax

    mov  cx,n

    dec  cx    ; 設置count1

    loop1:

    mov  di,cx   ; 保存count1

    mov  si, 0    ; 初始化si

    loop2:

    mov  ax,a[si]

    cmp  ax,a[si+2]  ; Ki與Ki+1比較

    jle  continue   ; 如果Ki≤Ki+1,不交換

    xchg ax,a[si+2]

    mov  a[si],ax   ; 如果Ki>Ki+1,交換

    continue:

    add  si,2    ; 修改地址

    loop  loop2   ; 內循環

    mov  cx,di   ; 恢復count1

    loop  loop1   ; 外循環

    mov  ax,4c00h

    int  21h

    main  endp

    cseg  ends

    end  start

看過《循環程序的設計》的人還看了以下文章:

發表評論

最新評論

|電工學習網 ( )

GMT+8, 2020-2-29 18:36

Powered by © 2011-2020 www.jeefkt.live 版權所有 免責聲明 不良信息舉報

技術驅動未來! 電工學習網—專業電工基礎知識電工技術學習網站。

欄目導航: 工控家園 | 三菱plc | 西門子plc | 歐姆龍plc | plc視頻教程

返回頂部
黑龙江快乐10分开奖查询 贵州矛台股票行情 投资理财平台倒闭了我里面的钱怎么办 顶级配资 禾百在线 互联网理财平台排行 南洋股份股吧 股票行情今天医药板块 政府基金配资 股票涨跌跟什么有关系 股巢网配资 股票配资平台代理选哪个 中国银行股票行情 京海策略 益丰配资 基金配资条件 现在什么股票好