彙編實驗小記(五)-迴圈程式設計

Ajiajiajia發表於2018-05-08
  • 兩種迴圈結構
    • DO WHILE的迴圈結構用CMP指令和條件轉移指令構成
    • while少用
  • 迴圈指令:loop,loope,loopne
  • 偽指令 EQU 及操作符 '$'的使用
  • 多重迴圈中,可以由內層迴圈向外層迴圈跳轉,或者直接向外層程式跳轉,但是不允許從外向內跳轉
  • 會用迴圈實現排序演算法

1.寫出y=5!的程式段

loop指令

cpu執行loop指令的時候,要進行兩步操作

LOOP Lable
  • (cx)=(cx)-1
  • 判斷cx中的值,不為零則轉至Lable執行,如果為零,則向下執行

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

data segment
t db '0123456789ABCDEF'
info db 'y = 5! $'
data ends
code segment
assume cs:code,ds:data
start:
	mov ax,data
	mov ds,ax

	mov dx,offset info
	mov ah,9
	int 21h
			
	mov al,1 ;起始值:用於儲存乘積
	mov bl,2 ;乘數起始值

	mov cx,4 ; 2*3*4*5 總共進行4次乘法運算->迴圈次數
	s:
	mul bl ;5!=120 8位二進位制足以表示,所以可以放在al中,就不用ax了
	inc bl
	loop s

	mov bp,4 ;輸出為4位數的16進位制,所以需要輸出4次

	s1:   ;將結果按照16進位制數輸出
	mov cl,4  ;右移位數
	rol ax,cl
	mov si,ax
	and ax,0fh

	mov bx,ax
	mov dl,t[bx] ;找到對應的16進位制數並輸出
	mov ah,2
	int 21h

	mov ax,si ;每次在右移之前就先儲存
	dec bp
	jnz s1 ;bp不為0說明4位數還沒有輸出夠,所以繼續

	mov ah,4ch
	int 21h

code ends
end start
複製程式碼

2.查詢出陣列中的負數,並顯示位置id(起始位置從0開始)

1.LOOPZ/LOOPE指令

cpu執行loopz指令的時候,要進行兩步操作

LOOPZ/LOOPE Lable
  • (cx)=(cx)-1
  • 若CX!=0並且同時ZF=1 則轉至Lable執行,如果為零,則向下執行

2.ZF--零標誌,稍後看debug中分步執行

彙編實驗小記(五)-迴圈程式設計

本題使用:【⚠️棧-儲存資料】

彙編實驗小記(五)-迴圈程式設計

data segment
	t1 db 1,2,3,4,-5,255,127
	t db '0123456789ABCDEF' ;用於二進位制計算後對應過來找16進位制數
	info db 0dh,0ah,'the id of first negtuve number is : $'
	count equ $-t1
data ends
stack segment
	db 512 dup(?) ;使用棧段
stack ends
code segment
assume cs:code,ds:data
	start:

	mov ax,data
	mov ds,ax

	mov ax,stack
	mov ss,ax

	mov sp,512

	mov dx,offset info
	mov ah,9
	int 21h

	mov bx,0

	mov cx,count ;迴圈中每次自動(cx)=(cx)-1    
	s:
	mov al,t1[bx]
	inc bx 
	and al,80h
	loopz s ;判斷cx中的值,不為零則轉至標號處執行,如果為零,則向下執行

	dec bx ;由於上面的迴圈中s進行了自增,我們需要的指示數是從0開始,所以需要減1
	mov ax,bx  

	mov cx,4 ;轉化成4位的十六進位制數進行輸出
	s1:
	push cx
	mov cl,4
	rol ax,cl
	mov si,ax
	and ax,0fh
	mov bx,ax
	mov dl,t[bx]

	mov ah,2
	int 21h

	mov ax,si
	pop cx
	loop s1

	add si,2
	
	mov ah,4ch
	int 21h

code ends
end start
複製程式碼

分步除錯看loopz的用法標尺-ZF

若CX!=0並且同時 ZR 則轉至Lable執行(繼續迴圈),如果為NZ,則向下執行其他程式程式碼

ZF-零標誌

  • 1:ZR
  • 0:NZ

彙編實驗小記(五)-迴圈程式設計

還未查詢到負數的時候:

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

找到負數:

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

3.1、 查詢CATI表中的字元@,找到後,輸出其所在位置

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

data segment
	t1 db '1234567890@sdfghj'
	t db '0123456789ABCDEF' ;用於二進位制計算後對應過來找16進位制數
	info db 0dh,0ah,'the id of @  is : $'
	count equ $-t1
data ends
stack segment
	db 512 dup(?)
stack ends
code segment
assume cs:code,ds:data,es:data
	start:

	mov ax,data
	mov ds,ax
	mov es,ax

	mov ax,stack
	mov ss,ax

	mov sp,512

	mov dx,offset info ;提示資訊
	mov ah,9
	int 21h

	mov al,'@'
	mov di,offset t1 ;取陣列t1的首地址到di暫存器中 
	mov cx,count 

	cld  ;clear df    將方向標誌位DF清零 課本20頁 0-up,1-down,一直向右
	repne scasb ;找到與al相同的數就退出掃描   一直重複搜尋到t1字串末尾  課本134 

	;但存在問題:此時,cx沒有減為0,但是di已經增加1,所以下面需要減1

	;	注意:在掃描時,他是先進行di所在位置的數進行比較,無論相等還是不想等,他都會自動執行di+1
	dec di ;由於上面的迴圈中s進行了自增,相等了跳出,但此時di多加了1,想要的到我們的數就需要減1
	mov ax,di 

	mov cx,4

	s1:
	push cx
	mov cl,4 ;由於這裡會改變cx的值,所以在上面需要先將cx入棧進行儲存
	rol ax,cl
	mov si,ax
	and ax,0fh
	mov bx,ax
	mov dl,t[bx]

	mov ah,2
	int 21h

	mov ax,si
	pop cx

	loop s1 ;每次執行完

	add si,2

	mov ah,4ch
	int 21h

code ends
end start
複製程式碼

4.氣泡排序

1.jae (cf-進位標誌)

  • 轉移條件:cf=0
  • 用於無符號
  • 大於或等則跳轉

2.cmp

彙編實驗小記(五)-迴圈程式設計

  • cmp eax, ebx (eax - ebx = 03h)
  • 不儲存結果,只是根據結果修改相應的標誌位

3.xchg

交換兩個運算元的資料

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

;每一趟氣泡排序都會將最小的浮到最下面
;指向最後一個數,和倒數第二個數進行比較--比較係數在自減
data segment
	t1 db 5,6,1,7,4,3,2
	count equ $-t1
data ends
code segment
assume cs:code,ds:data
start:

	mov ax,data
	mov ds,ax

	mov cx,count 
	dec cx

	bubble:
		push cx

	mov bx,count
	dec bx 

	change:
		mov al,t1[bx]
		cmp al,t1[bx-1]
		jae next ;滿足條件 -> next; jae轉移條件:cf=0 	大於等於 -> 轉移 

		xchg al,t1[bx-1] ;不滿足條件 (小於)則進行交換
		mov t1[bx],al

	next: 
		dec  bx
		loop change

	pop cx
	loop bubble

	mov ah,4ch
	int 21h

code ends
end start
複製程式碼

單步檢視每一次排序後的結果

初始資料:t1 db 5,6,1,7,4,3,2

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

彙編實驗小記(五)-迴圈程式設計

【注意⚠️】

剛開始進入的是小迴圈後,就一直t.....t到第二次小迴圈的loop ,然後再 p d

彙編實驗小記(五)-迴圈程式設計

  • 第一次遇到的是小迴圈,第二次遇到的大迴圈

相關文章