六、選擇結構
if-then結構
C語言版本
if(count == 10) { count --; i++; }
MASM匯編
.if count==10 dec count inc i .endif
cmp指令,該指令用於比較兩個參數大小
cmp mem, imm 比較內存mem和立即數imm大小
cmp reg, imm 比較寄存器reg和立即數imm大小
cmp reg, mem 比較寄存器reg和內存mem大小
cmp mem, reg 比較內存mem和寄存器reg大小
cmp imm, reg 比較立即數和寄存器reg大小
cmp imm, mem比較立即數和內存mem大小
cmp reg, reg比較兩個寄存器數據大小
.if 內部是通過cmp實現的,.if和cmp都不能比較兩個內存中數據大小
條件跳轉指令
je 相等時跳轉
jne 不相等時跳轉
je 和jne可以用於無符號數比較跳轉,也可用於符號數比較跳轉
符號數據跳轉指令
jg 大於時跳轉
jge 大於或等於時跳轉
jl 小於是跳轉
jle 小於或等於時跳轉
jnle 不小於且不等於時跳轉,即大於時跳轉
jnl 不小於時跳轉
jnge 不大於且不等於時跳轉
jng 不大於時跳轉
這類指令可用上面的jg,jge,jl,jle替代,盡量不要使用,
不容易理解。
.if-.end匯編指令可用上面的cmp指令和條件跳轉指令替代
如
.if number == 0 dec number .endif
用條件跳轉指令實現為:
if01: cmp number, 0 jne endif01 then01: dec number endif01: nop
if-then-else結構
匯編指令的結構為
.if 條件 ;執行語句 .else ;執行語句 .endif
舉例說明,C語言
if (x>=y) x--; else y--;
匯編語言
if01: mov eax,x cmp eax,y jl else01 then03: dec x jmp endif01 else01: dec y endif01: nop
采用匯編指令
mov eax , x .if eax >= y dec x .else dec y .endif
嵌套if結構
C語言
if(x < 50) y++; else if(x <= 100) y = 0; else y--;
匯編語言
采用匯編指令
.if x < 50 inc y .elseif x <= 100 mov y, 0 .else dec y .endif
通過跳轉指令實現上述步驟
if01: cmp eax, 50 jge else01 then01: inc y jmp endif01 else01: nop if02: cmp x, 100 jg else02 then02: mov y,0 jmp endif01 else02: dec y endif01: nop
case 結構
C語言
switch(w) { case 1: x++; break case 2: case 3: y++; break; default: z++; }
匯編語言中沒有case switch對應的匯編指令,但是可以通過cmp指令和跳轉指令實現
switch01: cmp w, 1 je case1 cmp w,2 je case2 cmp w,3 je case2 jmp default01 case1: inc x jmp endswitch01 case2: inc y jmp endswitch01 default01 : inc z endswitch01: nop
無符號跳轉指令
ja 高於跳轉
jae 高於或等於跳轉
jb 低於跳轉
i = 1; while(i <= 3) { i++; }
jbe 低於或等於時跳轉
邏輯運算符綜合實現
.if w==1 || x==2&&y == 3 inc z .endif
條件跳轉指令實現上述邏輯
if01: cmp w,1 jne or01 or01: cmp x, 2 jne endif01 cmp y, 3 jne endif01 then01: inc z endif01: nop
七、迭代結構
1 前置循環結構while
C語言
i = 1; while(i <= 3) { i++; }
匯編指令實現
mov i, 1 .while (i <= 3) inc i .endw
條件跳轉指令實現
mov i, 1 while01: cmp i, 3 jg endw01 inc i endw01: nop
2 后置循環結構 do while
C語言
i = 1; do { i++; }while(i <= 3);
匯編指令 .repeat .until
mov i, 1 .repeat inc i .until i > 3
.repeat-.until和C語言do -while一樣,第一次先執行循環體內容,do-while是在每次運行循環體后判斷條件不滿足跳出循環,
.repeat-.until 是判斷條件不滿足則一直循環,直到.until后面條件成立則跳出循環。
通過匯編跳轉指令實現
mov i, 1 repeat01: nop inc i cmp i, 3 jle repeat01 endrpt01: nop
3 固定循環結構 for
C語言
for(i=1; i <= 3; i++) { //循環體 }
匯編語言
mov ecx, 3 .repeat ; 循環體 .untilcxz
.repeat-.untilcxz 對應C語言的for循環固定循環結構,它和.repeat-.until都是后置循環結構。
都要先執行一次循環體,然后.untilcxz會將ecx中的數據值減1,接着判斷ecx是否為0,ecx為0則跳出循環
ecx大於0則繼續執行循環。所以執行.repeat-.untilcxz這個循環前保證ecx大於0
.repeat-.untilcxz 內部是loop實現的,所以同樣可以通過loop實現該循環
mov ecx, 3 for01 : nop ; 循環體 loop for01 endfor01: nop
loop 和.untilcxz一樣,都會將ecx中的值減1,然后判斷ecx是否為0,為0則終止循環,大於0則繼續循環。
loop指令最多只能向前跳轉128字節處,也就是循環體內容不得超過128字節。同樣.repeat-.untilcxz循環體也不得超過128字節。
與.if高級匯編指令一樣,.while-end高級匯編指令和.repeat-.until高級匯編指令都基於cmp,不可直接比較兩個內存變量。
使用loop指令和.repeat-untilcxz指令前,需要保證ecx大於0,在循環體中盡量不要更改ecx數值,如果需要更改則將ecx
數據先保存在內存中,執行完相關操作后將ecx數值還原,保證.untilcxz和loop操作ecx的准確性。
下面用匯編語言實現斐波那契數列
if n= 0, then 0
if n = 1, then 1
if n = 2, then 0+ 1 = 1
if n = 3, then 1+ 1 = 2
if n = 4, then 1+2 = 3
n 為任意非負數,計算n對應的數值sum。
用.while循環實現如下
.if n==0
mov sum, 0
.endif
.if n==1
mov sum, 1
.endif
mov ecx, n
mov eax, 0
mov sum, 1
.while (ecx <= n)
mov ebx, sum
add sum, eax
mov eax, ebx
.endwhile
到目前為止,循環和條件判斷就介紹到這里,下一期介紹堆棧位移之類的指令。
我的公眾號: