彙編學習 分支與迴圈

2021-09-07 10:35:10 字數 4623 閱讀 2073

在高階語言程式設計中,我們不僅要求程式可以順序執行,還要求其可以執行不同分支,或者反覆執行某些操作。在組合語言中,相同具有相同的能力,可以由對應的指令來控制程式的執行流程。由於畢竟高階語言都是彙編實現的,僅僅是不直觀而已。

無條件轉移為

jmp。類似

c語言中的

goto

。 在

c語言中,goto

是不推薦使用的,會使程式難以控制和理解,但在彙編中,沒有對應的

if 和

while

語句。僅僅能使用

jmp來完畢邏輯複雜的控制結構。

jmp分為段內轉移和段間轉移。只是在

windows

程式設計上,乙個**段的大小為4g

b。一般不須要段間轉移。

條件轉移是由

cpu提供多個標誌位,在執行這類指令之前。檢查之前已經設定的標誌位的狀態來決定是否進行轉移。能夠想象,通過條件轉移。能夠實現分支和迴圈。

在彙編中,設計乙個分支結構的思路基本是這種。由條件轉移指令來推斷條件是否滿足,若滿足,則跳過分支程式。否則繼續向下執行,最後會合。

程式

int x = 10;

int signx;

int main()

相應的彙編

x                sdword        -45

signx sdword ?

mov signx, 0

cmp x, 0

jz a70 ;為0

jg a60 ;大於0

mov signx, -1

jmp a70

a60:

mov signx, 1

a70:

二分查詢

對於乙個已排序的陣列,最快的查詢乙個元素的方法不是順序查詢。而是二分查詢。這個用

c 語言寫很方便。首先我們還是畫出流程圖,這有助於我們用

jmp轉換之。

陣列為r,元素個數為

n。要查詢的數為

執行過程為:(1

)先設定查詢範圍為下界

l到上界h

(2)假設下界大於上界,且沒查到。則查詢失敗

(3)取下界和上界的中點

m=(l+h)/2

,該數為

r[m]

(4)若該數為

a,則演算法結束

(5)若該數小於

a。則改動下界

l=m+1

,並跳轉到第二步

(6)若該數大於

a,則改動上界

h=m-1

,並跳轉到第二步

彙編源**

.386

.model flat,stdcall

optioncasemap:none

includelib msvcrt.lib

printf proto c :dword, :vararg

.data

darray dword 50, 56, 64, 73, 83, 92, 103, 105

items equ $-darray)/4 ; 陣列長度

index dword ?

count dword ?

szfmt byte 'index=%d count=%d element=%d', 0; 格式化字串

szerr byte 'not found'

l sdword ?

h sdword ? m sdword ? a sdword 83 ; 所查詢的數字 .code start: mov index, -1; mov count, 0 mov l, 0 mov h, items-1; mov ecx, l mov edx, h b10: cmp ecx, edx ; 下界和上界比較 jg b40 ; 超出。則未找到 mov esi, ecx; add esi, edx shr esi, 1 ; m = (l+h)>>1 inc count mov eax, a ; 取出被比較的數 cmp eax, darray[esi*4] ; 取出該數 jz b30 ; 相等 jg b20 ; 比 a 小,改動下界 ; 比 a 大,改動上界 mov edx, esi dec edx ; h = m-1 jmp b10 b20: mov ecx, esi inc ecx ; l = m+1 jmp b10 b30: mov index, esi ; 呼叫 c 庫的 printf invoke printf, offset szfmt, index, count, darray[esi*4] jmp b50 b40: ; 查詢失敗 invoke printf, offset szerr b50: ret end start

有序表插入

首先遍歷陣列。找到

m,滿足

r[m-1]a

。 然後將

r[m..n-1]

每個元素向後移動乙個位置,再插入a。

關鍵部分彙編**

start:

mov eax, element ; 將插入的元素

mov esi, 0 ; 當前比較元素的下標

c10:

cmp darray[esi*4], eax

ja c20

inc esi

cmp esi, items ; 超出陣列長度,

jb c10 ; 沒有超出

;c20:

mov edi, items-1 ; 從陣列尾部開始移動

c30:

cmp edi, esi ; 與插入位置比較

jl c40 ; 移動完畢

; 還沒完畢,繼續移動

mov ebx, darray[edi*4]

mov darray[edi*4+4], ebx ; 向後移動乙個元素

dec edi

jmp c30 ; 繼續推斷。決定是否移動

c40:

mov darray[esi*4], eax ; 移動完畢,插入元素

迴圈實際編碼解決這個問題時,常常遇到大量反覆的動作,利用迴圈結構能夠簡化程式的編寫。

實際在上文中,已經有迴圈部分出現,但那是不定次數的迴圈。

乙個迴圈結構分為三部分:迴圈初始化,迴圈體,迴圈結束控制。

乙個固定次數的迴圈,有

loop

命令來實現。迴圈次數在

ecx中。

階乘這裡直接使用

ecx

作為乘數。其會隨迴圈遞減。正好符合階乘的定義。

.data

fact dword ?

n equ 5

.code

start:

mov ecx, n ; 迴圈初值,同一時候也是乘數初值

mov eax, 1 ; fact 初值

e10:

imul eax, ecx ; 相乘

loop e10

mov fact, eax ; 階乘結果

冒泡冒泡演算法是乙個多重迴圈。

start:

mov ecx, items-1

i10:

xor esi, esi ; 清零

i20:

mov eax, darray[esi*4]

mov ebx, darray[esi*4+4]

cmp eax, ebx ; 比較相鄰的兩個數

jl i30

mov darray[esi*4], ebx ;較大的數在左邊。須要移動

mov darray[esi*4+4], eax ; 須要交換兩個數

; 比較下一對數

i30:

inc esi

cmp esi, ecx

jb i20 ; 內迴圈。一遍下來,最大的數,移到了最右邊

loop i10 ; 外迴圈

參考文獻

[1] 譚毓安, 張雪蘭. windows組合語言程式設計教程. 北京: 電子工業出版社, 2005.

彙編實驗 分支迴圈結構程式練習

一 實驗內容 試編寫程式,完成下面功能 1 程式執行時,顯示提示資訊 please input a string length 9 由使用者輸入乙個長度小於9的字串 2 然後顯示提示資訊 please input the index of the char to display 請使用者指定該串中的...

分支與迴圈(3)

while迴圈 語法 while 條件 執行迴圈體 例 age 23 while age 18 print 成年人 for迴圈語法 for 目標 in 表示式 執行迴圈體 例 range 語法 range start,stop step 1 這個bif有三個引數,其中用括號括起來的兩個表示這兩個引數...

分支與迴圈語句

練習 列印1 100之間的奇數 include include int isodd int x return 1 int main i system pause return 0 侷限性 1.若忘記break,會繼續執行 2.case語句中無法定義變數 3.case語句判定的條件必須是int lon...