最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

5.13 匯編語言:仿寫For循環(huán)語句

2023-08-31 12:59 作者:bili_42682284418  | 我要投稿

循環(huán)語句(for)是計算機編程中的一種基本控制結(jié)構(gòu),它允許程序按照指定的次數(shù)或范圍重復(fù)執(zhí)行一段代碼塊。for循環(huán)在處理需要進(jìn)行迭代操作的情況下非常有用,它使得程序可以更加方便地控制循環(huán)的次數(shù)。一般來說,for循環(huán)由三個部分組成:初始化部分、條件表達(dá)式和更新部分,以及一個需要重復(fù)執(zhí)行的代碼塊。在每次循環(huán)迭代開始時,程序首先執(zhí)行初始化部分,然后檢查條件表達(dá)式的值,如果為真,則執(zhí)行代碼塊,并在每次循環(huán)結(jié)束后執(zhí)行更新部分。只要條件表達(dá)式為真,for循環(huán)就會一直重復(fù)執(zhí)行;一旦條件表達(dá)式為假,循環(huán)將停止,程序繼續(xù)執(zhí)行循環(huán)之后的代碼。

11.14 FOR 循環(huán)結(jié)構(gòu)優(yōu)化

For語句先初始化條件變量,然后在判斷是否符合條件,符合則執(zhí)行循環(huán)體,不符合則跳過執(zhí)行。For循環(huán)結(jié)構(gòu)的效率最低,該語句的構(gòu)建往往需要三個跳轉(zhuǎn)來實現(xiàn),首先需要初始化變量此處要進(jìn)行一次判斷,其次是內(nèi)部循環(huán)體需要另一個判斷通常用于實現(xiàn)跳出循環(huán)體,最后一步則需要一個無條件跳轉(zhuǎn)指令跳回到循環(huán)首地址,但在開啟了O2優(yōu)化時編譯器也會盡可能將其轉(zhuǎn)換為While語句,如果可以還會繼續(xù)將While轉(zhuǎn)為帶有IF語句的Do循環(huán)來提高執(zhí)行效率。

??.386p
??.model?flat,stdcall
??option?casemap:none

include?windows.inc
include?kernel32.inc
includelib?kernel32.lib

.data
??count?DWORD??
.code
??main?PROC
????mov?dword?ptr?ds:[count],0??????????;?設(shè)置?int?x?=?0;
????jmp?L2

??L1:
????mov?eax,dword?ptr?ds:[count]????????;?x?=?x++
????add?eax,1
????mov?dword?ptr?ds:[count],eax

??L2:
????cmp?dword?ptr?ds:[count],10?????????;?比較?x?<?10
????jge?lop_end
????
????xor?eax,eax?????????????????????????;?執(zhí)行循環(huán)體
????jmp?L1
????
??lop_end:
????int?3
????invoke?ExitProcess,0
??main?ENDP
END?main

雖然For語句在執(zhí)行效率上來說是最低的,但該語句的使用確是最符合我們思維方式的,在高級語言中應(yīng)用最為廣泛,例如在Python中For循環(huán)體被簡化成了for x in range(2,10)它可以指定一個循環(huán)范圍,該語句利用匯編完全也可以被構(gòu)建出來,我們接著嘗試構(gòu)建一下這個特別的循環(huán)體。

??.386p
??.model?flat,stdcall
??option?casemap:none

include?windows.inc
include?kernel32.inc
includelib?kernel32.lib

.data
??start_count?DWORD??
??end_count?DWORD??
.code
??main?PROC
????mov?dword?ptr?ds:[start_count],2?????;?指定開始循環(huán)編號
????mov?dword?ptr?ds:[end_count],5???????;?指定結(jié)束循環(huán)編號
????
????mov?ecx,dword?ptr?ds:[start_count]
??L1:
????cmp?dword?ptr?ds:[end_count],ecx
????jle?lop_end
????
????xor?eax,eax??????????????????????????;?循環(huán)體內(nèi)部
????
????add?ecx,1????????????????????????????;?每次遞增
????mov?dword?ptr?ds:[start_count],ecx
????jmp?L1
????
??lop_end:
????int?3
????invoke?ExitProcess,0
??main?ENDP
END?main

11.20 仿寫For水仙花數(shù)

該C++代碼實現(xiàn)了水仙花數(shù)的查找算法,水仙花數(shù)是指一個三位數(shù),它的每個位上的數(shù)字的立方和等于它本身。在循環(huán)中,遍歷100~999之間的每一個數(shù),將其分解為三個數(shù)(百、十、個位),再將三個數(shù)分別平方并相加,判斷與原數(shù)是否相等,如果相等則輸出該數(shù)即為水仙花數(shù)。

  • ??例如: 153是一個水仙花數(shù),因為153等于1的3次方加上5的3次方加上3的3次方

#include?<stdio.h>
#include?<Windows.h>

int?main(int?argc,?char?*argv[])
{
??int?x,?y,?z,?n;
??for?(n?=?100;?n?<?1000;?n++)
??{
????x?=?n?/?100;??????????//?分解百位
????y?=?n?/?10?%?10;??????//?分解十位
????z?=?n?%?10;???????????//?分解個位
????if?(x?*?100?+?y?*?10?+?z?==?x*x*x?+?y*y*y?+?z*z*z)
????{
??????printf("水仙花:?%-5d?\n",?n);
????}
??}

??system("pause");
??return?0;
}

嘗試使用匯編實現(xiàn)計算邏輯,這段代碼沒有任何難度,因為并不會涉及到嵌套循環(huán)的問題,只是在計算四則運算時需要格外注意些。

??.386p
??.model?flat,stdcall
??option?casemap:none

include?windows.inc
include?kernel32.inc
includelib?kernel32.lib

include?msvcrt.inc
includelib?msvcrt.lib

.data
??x?DWORD??
??y?DWORD??
??z?DWORD??
??n?DWORD??
??szFmt?BYTE?'水仙花:?%-5d?',0dh,0ah,0

.code
??main?PROC
????mov?dword?ptr?ds:[n],100?????;?n?=?100
????jmp?L1
??L2:?mov?eax,dword?ptr?ds:[n]
????add?eax,1????????????????????;?n++
????mov?dword?ptr?ds:[n],eax
??L1:?mov?eax,dword?ptr?ds:[n]
????cmp?eax,1000?????????????????;?n?<?1000
????jge?lop_end
????
????mov?eax,dword?ptr?ds:[n]
????cdq
????mov?ecx,100??????????????????;?x?=?n?/?100;
????idiv?ecx
????mov?dword?ptr?ds:[x],eax
????
????mov?eax,dword?ptr?ds:[n]
????cdq
????mov?ecx,10
????idiv?ecx?????????????????????;?y?=?n?/?10;
????cdq
????mov?ecx,10
????idiv?ecx?????????????????????;?y?=?y?%?10;
????mov?dword?ptr?ds:[y],edx
????
????mov?eax,dword?ptr?ds:[n]
????cdq
????mov?ecx,10
????idiv?ecx?????????????????????;?z?=?n?%?10;
????mov?dword?ptr?ds:[z],edx
????
????;?開始執(zhí)行if()比較語句
????imul?eax,dword?ptr?ds:[x],100??;?x?*?100
????imul?ecx,dword?ptr?ds:[y],10???;?y?*?10
????add?eax,dword?ptr?ds:[z]???????;?+?z
????add?ecx,eax
????
????mov?edx,dword?ptr?ds:[x]
????imul?edx,dword?ptr?ds:[x]??????;?x*x*x
????imul?edx,dword?ptr?ds:[x]
????
????mov?eax,dword?ptr?ds:[y]
????imul?eax,dword?ptr?ds:[y]??????;?y*y*y
????imul?eax,dword?ptr?ds:[y]
????add?edx,eax
????
????mov?eax,dword?ptr?ds:[z]
????imul?eax,dword?ptr?ds:[z]??????;?z*z*z
????imul?eax,dword?ptr?ds:[z]
????add?edx,eax
????
????cmp?ecx,edx???;?(x?*?100?+?y?*?10?+?z)?==?(x*x*x?+?y*y*y?+?z*z*z)
????jne?L2
????
????mov?eax,dword?ptr?ds:[n]
????invoke?crt_printf,addr?szFmt,eax
????jmp?L2
????
??lop_end:
????int?3?

??main?ENDP
END?main

11.21 For循環(huán)嘗試判斷

該C++代碼實現(xiàn)了一個簡單的循環(huán),遍歷數(shù)組中的所有元素并輸出大于等于50的元素。在循環(huán)中,通過判斷Array數(shù)組中每個元素與50的大小關(guān)系,如果元素大于等于50,則使用printf函數(shù)輸出該元素的值。最終程序輸出所有大于等于50的元素。

#include?<stdio.h>
#include?<Windows.h>

int?main(int?argc,char?*argv[])
{
??int?Array[10]?=?{?56,78,33,45,78,90,32,44,56,67?};

??for?(int?x?=?0;?x?<?10;?x++)
??{
????if?(Array[x]?>=?50)
????{
??????printf("out?->?%d?\n",?Array[x]);
????}
??}
??return?0;
}

上述C語言代碼如果通過匯編語言實現(xiàn)可以寫成如下樣子,讀者可自行理解流程;

??.386p
??.model?flat,stdcall
??option?casemap:none

include?windows.inc
include?kernel32.inc
includelib?kernel32.lib

include?msvcrt.inc
includelib?msvcrt.lib

.data
??MyArray?DWORD?56,78,33,45,78,90,32,44,56,67
??count?DWORD??
??szFmt?BYTE?'out?->?%d?',0dh,0ah,0

.code
??main?PROC
????
????mov?dword?ptr?ds:[count],0??????;?int?x?=?0
????jmp?L1
??L2:?mov?eax,dword?ptr?ds:[count]
????add?eax,1???????????????????????;?x?++
????mov?dword?ptr?ds:[count],eax
??L1:
????cmp?dword?ptr?ds:[count],10?????;?x?<?10
????jge?lop_end
????
????mov?eax,dword?ptr?ds:[count]??????????;?獲取循環(huán)次數(shù),當(dāng)作因子
????lea?esi,dword?ptr?ds:[MyArray]????????;?取數(shù)組基地址
????mov?ebx,dword?ptr?ds:[esi?+?eax?*?4]??;?因子尋址
????cmp?ebx,50
????jl?L2?????????????????????????????????;?如果小于50則跳轉(zhuǎn)到下一次循環(huán)
????
????invoke?crt_printf,addr?szFmt,ebx??????;?調(diào)用系統(tǒng)crt
????jmp?L2

??lop_end:
????int?3
??
????invoke?ExitProcess,0
??main?ENDP
END?main

在讀者學(xué)會了上述代碼編寫之后,我們繼續(xù)增加代碼的復(fù)雜度,如下所示代碼實現(xiàn)了對整型數(shù)組的最大值、最小值、元素總和以及平均值的計算。在循環(huán)中,通過依次遍歷數(shù)組中的每一個元素,維護(hù)一個當(dāng)前最大值max_result和最小值min_result,并對元素進(jìn)行累加求和,最終計算出數(shù)組中所有元素的平均值avg_result。代碼中使用printf函數(shù)輸出求得的四個值(max、min、sum、avg),并使用system函數(shù)暫停程序以便觀察輸出結(jié)果。

#include?<stdio.h>
#include?<Windows.h>

int?main(int?argc,?char?*argv[])
{
??int?Array[10]?=?{?56,78,33,45,78,90,32,44,56,67?};
??int?max_result?=?0,min_result?=?100,sum_result?=?0,avg_result?=?0;

??for?(int?x?=?0;?x?<?10;?x++)
??{
????if?(Array[x]?>=?max_result)
????{
??????max_result?=?Array[x];
????}
????if?(Array[x]?<=?min_result)
????{
??????min_result?=?Array[x];
????}
????sum_result?=?sum_result?+?Array[x];
????avg_result?=?sum_result?/?10;
??}
??printf("max?=?%d?min?=?%d?sum?=?%d?avg?=?%d?\n",?max_result,min_result,sum_result,avg_result);
??system("pause");
??return?0;
}

上述代碼讀者可嘗試使用匯編語言來實現(xiàn)一下,如下代碼是筆者思考后編寫出來的實現(xiàn)流程,讀者可自行對照參考;

??.386p
??.model?flat,stdcall
??option?casemap:none

include?windows.inc
include?kernel32.inc
includelib?kernel32.lib

include?msvcrt.inc
includelib?msvcrt.lib

.data
??MyArray?DWORD?56,78,33,45,78,90,32,44,56,67
??count?DWORD??
??max_result?DWORD?0
??min_result?DWORD?100
??sum_result?DWORD?0
??avg_result?DWORD?0
??
??szFmt?BYTE?'max?=?%d?min=?%d?sum=?%d?avg?=?%d?',0dh,0ah,0

.code
??main?PROC
????mov?dword?ptr?ds:[count],0??????;?int?x?=?0
????jmp?L1
??L2:?mov?eax,dword?ptr?ds:[count]
????add?eax,1???????????????????????;?x?++
????mov?dword?ptr?ds:[count],eax
??L1:
????cmp?dword?ptr?ds:[count],10?????;?x?<?10
????jge?lop_end

????mov?eax,dword?ptr?ds:[count]
????lea?esi,dword?ptr?ds:[MyArray]
????
????mov?ebx,dword?ptr?ds:[esi?+?eax?*?4]
????cmp?ebx,dword?ptr?ds:[max_result]??????;?Array[x]?>=?max_result
????jl?L3
????mov?dword?ptr?ds:[max_result],ebx??????;?max_result?=?Array[x];
??L3:
????mov?ebx,dword?ptr?ds:[esi?+?eax?*?4]
????cmp?ebx,dword?ptr?ds:[min_result]??????;?Array[x]?<=?min_result
????jg?L4
????mov?dword?ptr?ds:[min_result],ebx

??L4:
????mov?ebx,dword?ptr?ds:[esi?+?eax?*?4]???;?Array[x]
????add?dword?ptr?ds:[sum_result],ebx??????;?sum_result?=?sum_result?+?Array[x];
????
????mov?eax,dword?ptr?ds:[sum_result]
????cdq????????????????????????????????????;?符號擴展
????mov?ecx,10?????????????????????????????;?/?10
????idiv?ecx???????????????????????????????;?sum_result?/?10;
????mov?dword?ptr?ds:[avg_result],eax??????;?avg_result
????jmp?L2
????
??lop_end:
????mov?eax,dword?ptr?ds:[max_result]
????mov?ebx,dword?ptr?ds:[min_result]
????mov?ecx,dword?ptr?ds:[sum_result]
????mov?edx,dword?ptr?ds:[avg_result]
????invoke?crt_printf,addr?szFmt,eax,ebx,ecx,edx
????int?3
??main?ENDP
END?main

11.22 For循環(huán)多重IF判斷

該C++代碼實現(xiàn)了對兩個數(shù)組進(jìn)行元素相加,并輸出相加結(jié)果的奇偶性。在循環(huán)中,對SrcArrayDstArray兩個數(shù)組中的元素相加,如果兩個元素均不為0,則判斷相加的結(jié)果是否為偶數(shù),如果是,則使用printf函數(shù)輸出偶數(shù)sum的形式,否則輸出基數(shù)sum的形式。其中sum表示兩個元素相加的結(jié)果。代碼中使用system函數(shù)暫停程序以便觀察輸出結(jié)果。

#include?<stdio.h>
#include?<Windows.h>

int?main(int?argc,?char?*argv[])
{
??int?SrcArray[10]?=?{?56,78,33,45,78,90,32,15,56,67?};
??int?DstArray[10]?=?{?59,77,89,23,11,45,67,88,93,27?};
??int?index?=?0;

??for?(index?=?0;?index?<?10;?index++)
??{
????if?(SrcArray[index]?!=?0?&&?DstArray[index]?!=?0)
????{
??????int?sum?=?SrcArray[index]?+?DstArray[index];
??????if?(sum?%?2?==?0)
????????printf("偶數(shù):?%d?\n",?sum);
??????else
????????printf("基數(shù):?%d?\n",?sum);
????}
??}
??system("pause");
??return?0;
}

上述代碼片段的邏輯并不復(fù)雜,僅僅只是循環(huán)內(nèi)部嵌套雙層判斷,筆者思考片刻后即寫出了與之對應(yīng)的匯編代碼;

??.386p
??.model?flat,stdcall
??option?casemap:none

include?windows.inc
include?kernel32.inc
includelib?kernel32.lib

include?msvcrt.inc
includelib?msvcrt.lib

.data
??SrcArray?DWORD?56,78,33,45,78,90,32,15,56,67
??DstArray?DWORD?59,77,89,23,11,45,67,88,93,27
??index?DWORD?0
??sum?DWORD?0
??
??szFmt1?BYTE?'基數(shù):?%d?',0dh,0ah,0
??szFmt2?BYTE?'偶數(shù):?%d?',0dh,0ah,0

.code
??main?PROC
????mov?dword?ptr?ds:[index],0????????;?index?=?0
????
????jmp?L1
??L2:?mov?eax,dword?ptr?ds:[index]
????add?eax,1?????????????????????????;?index++
????mov?dword?ptr?ds:[index],eax
??L1:
????cmp?dword?ptr?ds:[index],10???????;?index?<?10
????jge?lop_end
????
????mov?eax,dword?ptr?ds:[index];
????cmp?dword?ptr?ds:[SrcArray?+?eax?*?4],0
????je?L2?????????????????????????????????????;?SrcArray[index]?!=?0
????
????mov?eax,dword?ptr?ds:[index]
????cmp?dword?ptr?ds:[DstArray?+?eax?*?4],0???;?DstArray[index]?!=?0
????je?L2
????
????;?------------------------------------------
????;?另類加法,通過一個SrcArray定位DstArray完成加法
????
????mov?eax,dword?ptr?ds:[index]?????????????????;?獲取因子
????lea?esi,dword?ptr?ds:[SrcArray]??????????????;?取數(shù)組首地址
????
????mov?ebx,dword?ptr?ds:[esi?+?eax?*?4]?????????;?獲取?SrcArray[index]
????mov?ecx,dword?ptr?ds:[esi?+?eax?*?4?+?40]????;?獲取?DstArray[index]
????add?ebx,ecx??????????????????????????????????;?SrcArray[index]?+?DstArray[index]
????mov?dword?ptr?ds:[sum],ebx???????????????????;?sum?=?SrcArray[index]?+?DstArray[index]
????
????mov?eax,dword?ptr?ds:[sum]
????and?eax,080000001h???????????????????????????;?sum?%?2?==?0
????test?eax,eax
????jne?L3
????
????invoke?crt_printf,addr?szFmt2,dword?ptr?ds:[sum]??;?偶數(shù)輸出
????jmp?L2
??L3:
????invoke?crt_printf,addr?szFmt1,dword?ptr?ds:[sum]??;?基數(shù)輸出
????jmp?L2
??lop_end:
????int?3

??main?ENDP
END?main

11.23 For嵌套乘法口訣表

該C++代碼實現(xiàn)了乘法口訣表的打印。在兩個for循環(huán)中,分別對x和y進(jìn)行遍歷,對每一次的遍歷輸出一個乘法口訣表的元素。代碼中使用printf函數(shù)實現(xiàn)輸出,并使用\n進(jìn)行換行。程序遍歷打印了從11到99的所有乘積的結(jié)果,這就是乘法口訣表。

#include?<stdio.h>
#include?<Windows.h>

int?main(int?argc,?char?*argv[])
{
??for?(int?x?=?1;?x?<?10;?x++)
??{
????for?(int?y?=?1;?y?<=?x;?y++)
????{
??????int?result?=?x*y;
??????printf("%d*%d=%-3d",?y,?x,?result);
????}
????printf("\n");
??}
??system("pause");
??return?0;
}

乘法口訣表的實現(xiàn)方法只需要嵌套兩層FOR循環(huán)語句,在使用匯編語言實現(xiàn)之前我們可以先來構(gòu)建出這個雙層循環(huán)體,如下代碼所示;

??.386p
??.model?flat,stdcall
??option?casemap:none

include?windows.inc
include?kernel32.inc
includelib?kernel32.lib

include?msvcrt.inc
includelib?msvcrt.lib

.data
??x?DWORD??
??y?DWORD??
??szFmt?BYTE?'內(nèi)層循環(huán):?%d?外層循環(huán):?%d?',0dh,0ah,0
??szPr??BYTE?'----->',0dh,0ah,0

.code
??main?PROC
????mov?dword?ptr?ds:[x],1????????;?int?x?=?1
????jmp?L1
??L2:?mov?eax,dword?ptr?ds:[x]
????add?eax,1?????????????????????;?x++
????mov?dword?ptr?ds:[x],eax
??L1:?
????cmp?dword?ptr?ds:[x],10???????;?x?<?10
????jge?lop_end

????mov?dword?ptr?ds:[y],1????????;?y?=?1
????jmp?L3
??L5:?mov?eax,dword?ptr?ds:[y]
????add?eax,1?????????????????????;?y++
????mov?dword?ptr?ds:[y],eax
??L3:
????mov?eax,dword?ptr?ds:[y]
????cmp?eax,dword?ptr?ds:[x]??????;?y?<=?x
????jg?L4
????
????;?執(zhí)行的是循環(huán)體內(nèi)部
????mov?eax,dword?ptr?ds:[x]
????mov?ebx,dword?ptr?ds:[y]
????invoke?crt_printf,addr?szFmt,eax,ebx
????
????jmp?L5
??L4:
????;?執(zhí)行外層循環(huán)
????invoke?crt_printf,addr?szPr

????jmp?L2
??lop_end:
????int?3

??main?ENDP
END?main

當(dāng)有了雙層循環(huán)體結(jié)構(gòu)之后,我們只需要再其循環(huán)之上增加一個乘法計算功能即可,完整的計算流程如下所示;

??.386p
??.model?flat,stdcall
??option?casemap:none

include?windows.inc
include?kernel32.inc
includelib?kernel32.lib

include?msvcrt.inc
includelib?msvcrt.lib

.data
??x?DWORD??
??y?DWORD??
??szFmt?BYTE?'%d?*?%d?=?%d?',0
??szPr??BYTE?'?',0dh,0ah,0
.code
??main?PROC
????mov?dword?ptr?ds:[x],1????????;?int?x?=?1
????jmp?L1
??L2:?mov?eax,dword?ptr?ds:[x]
????add?eax,1?????????????????????;?x++
????mov?dword?ptr?ds:[x],eax
??L1:?
????cmp?dword?ptr?ds:[x],10???????;?x?<?10
????jge?lop_end

????mov?dword?ptr?ds:[y],1????????;?y?=?1
????jmp?L3
??L5:?mov?eax,dword?ptr?ds:[y]
????add?eax,1?????????????????????;?y++
????mov?dword?ptr?ds:[y],eax
??L3:
????mov?eax,dword?ptr?ds:[y]
????cmp?eax,dword?ptr?ds:[x]??????;?y?<=?x
????jg?L4
????
????;?執(zhí)行的是循環(huán)體內(nèi)部
????mov?eax,dword?ptr?ds:[x]
????imul?eax,dword?ptr?ds:[y]
????invoke?crt_printf,addr?szFmt,dword?ptr?ds:[y],dword?ptr?ds:[x],eax
????
????jmp?L5
??L4:
????;?執(zhí)行外層循環(huán)
????invoke?crt_printf,addr?szPr

????jmp?L2
??lop_end:
????int?3

??main?ENDP
END?main

11.24 For語句冒泡排序

該C++代碼實現(xiàn)了冒泡排序算法對整型數(shù)組進(jìn)行排序。在冒泡排序算法中,數(shù)組中每兩個相鄰的元素,如果前一個元素大于后一個元素,則交換這兩個元素的位置。循環(huán)遍歷數(shù)組多次,每次將未排序的最大值向數(shù)組末尾冒泡,直到數(shù)組中的所有元素都排好序。代碼中使用兩層for循環(huán)實現(xiàn)排序,內(nèi)層循環(huán)從數(shù)組末尾開始,逐步向前遍歷,交換相鄰的兩個元素。外層循環(huán)控制排序的遍歷次數(shù),只有在當(dāng)前相鄰兩個數(shù)未排序時才進(jìn)行交換。程序最終輸出排序后的數(shù)組。

#include?<stdio.h>
#include?<Windows.h>

int?main(int?argc,?char?*argv[])
{
??int?Array[10]?=?{?34,78,65,77,89,43,23,55,67,8?};
??int?x,?y,?temporary,?ArraySize=10;

??for?(x?=?0;?x?<?ArraySize?-?1;?x++)
??{
????for?(y?=?ArraySize?-?1;?y?>?x;?y--)
????{
??????if?(Array[y?-?1]?>?Array[y])
??????{
????????temporary?=?Array[y?-?1];
????????Array[y?-?1]?=?Array[y];
????????Array[y]?=?temporary;
??????}
????}
??}

??for?(int?x?=?0;?x?<?10;?x++)
??{
????printf("%d?\n",?Array[x]);
??
??system("pause");
??return?0;
}

由于冒泡排序牽扯到了數(shù)據(jù)交換所以匯編版本可能稍顯負(fù)責(zé),不過大體框架還是沒有脫離二層循環(huán),僅僅只是在二層循環(huán)內(nèi)部增加了一個判斷流程而已,其實如果認(rèn)真構(gòu)建相信讀者也可以很容易的寫出來。

??.386p
??.model?flat,stdcall
??option?casemap:none

include?windows.inc
include?kernel32.inc
includelib?kernel32.lib

include?msvcrt.inc
includelib?msvcrt.lib

.data
??Array?DWORD?34,78,65,77,89,43,23,55,67,8
??x?DWORD??
??y?DWORD??
??Temporary?DWORD??
??ArraySize?DWORD??
??szFmt?BYTE?'%d?-->?%d?',0dh,0ah,0

.code
??main?PROC
????;?初始化的部分
????mov?dword?ptr?ds:[x],0????????????;?x=0
????mov?dword?ptr?ds:[ArraySize],10???;?ArraySize=10
????
????;?外層循環(huán)體
????jmp?L1
??L2:?mov?eax,dword?ptr?ds:[x]
????add?eax,1??????????????????????????;?x++
????mov?dword?ptr?ds:[x],eax
????
??L1:?mov?eax,dword?ptr?ds:[ArraySize]
????sub?eax,1??????????????????????????;?ArraySize?-?1
????cmp?dword?ptr?ds:[x],eax???????????;?x?<?ArraySize
????jge?lop_end
????
????;?內(nèi)層循環(huán)體內(nèi)容
????mov?eax,dword?ptr?ds:[ArraySize]
????sub?eax,1
????mov?dword?ptr?ds:[y],eax
????
????jmp?L3
??L4:?mov?eax,dword?ptr?ds:[y]
????sub?eax,1???????????????????????????;?y--
????mov?dword?ptr?ds:[y],eax
??
??L3:?mov?eax,dword?ptr?ds:[y]
????cmp?eax,dword?ptr?ds:[x]????????????;?Array[y?-?1]?>?Array[y]
????jle?L2
????
????;?尋址yy-1的位置
????mov?esi,dword?ptr?ds:[y]

????mov?ebx,dword?ptr?ds:[Array?+?esi?*?4]?????????;?Array[y]
????mov?edx,dword?ptr?ds:[Array?+?esi?*?4?-?4]?????;?Array[y?-?1]
????cmp?edx,ebx
????jle?L4
????
????;?數(shù)據(jù)交換
????mov?dword?ptr?ds:[Array?+?esi?*?4],edx?????????;?Array[y]?=?Array[y?-?1]
????mov?dword?ptr?ds:[Array?+?esi?*?4?-?4],ebx?????;?Array[y?-?1]?=?Array[y]
????;?invoke?crt_printf,addr?szFmt,ebx,edx
????
????jmp?L4
????jmp?L2

??lop_end:
????nop

????;?執(zhí)行打印函數(shù)
????mov?dword?ptr?ds:[Temporary],0

????jmp?L5
??L7:?mov?eax,dword?ptr?ds:[Temporary]
????add?eax,1
????mov?dword?ptr?ds:[Temporary],eax
??L5:
????mov?eax,dword?ptr?ds:[Temporary]
????cmp?eax,10
????jge?L6
????
????lea?esi,dword?ptr?ds:[Array]????????????????;?取數(shù)組基地址
????mov?esi,dword?ptr?ds:[Array?+?eax?*?4]??????;?比例因子尋址
????invoke?crt_printf,addr?szFmt,esi,esi
????jmp?L7
??L6:
????int?3

??main?ENDP
END?main

至此,匯編中的循環(huán)結(jié)構(gòu)仿寫就告一段落了,筆者提醒大家,由于匯編難度較大,且代碼都是線性的,所以在編寫之前要分析好主次關(guān)系,當(dāng)有了主次關(guān)系之后,我們就需要靜下心來,一個個構(gòu)建,由外到內(nèi)步步為營,其實匯編也并不是那么可怕。

本文作者: 王瑞 本文鏈接: https://www.lyshark.com/post/5e4fd192.html 版權(quán)聲明: 本博客所有文章除特別聲明外,均采用 BY-NC-SA 許可協(xié)議。轉(zhuǎn)載請注明出處!


5.13 匯編語言:仿寫For循環(huán)語句的評論 (共 條)

分享到微博請遵守國家法律
申扎县| 平舆县| 开阳县| 灵石县| 容城县| 荥经县| 杭州市| 绩溪县| 延边| 永泰县| 娄底市| 合作市| 海原县| 昭觉县| 弥勒县| 辽宁省| 通城县| 鞍山市| 青阳县| 卢湾区| 天全县| 岐山县| 天水市| 井陉县| 威宁| 彭阳县| 龙泉市| 旬阳县| 开江县| 临潭县| 永平县| 焉耆| 搜索| 类乌齐县| 凤冈县| 汾阳市| 读书| 广东省| 望都县| 永德县| 北安市|