c语⾔跳转指令实例,汇编语⾔条件跳转应⽤及⽰例
汇编语⾔做得最好的事情之⼀就是位测试。通常,不希望改变进⾏位测试的数值,但是却希望能修改 CPU 状态标志位的值。
条件跳转指令常常⽤这些状态标志位来决定是否将控制转向代码标号。例如,假设有⼀个名为 status 的 8 位内存操作数,它包含了与计算机连接的⼀个外设的状态信息。如果该操作数的位 5 等于 1,表⽰外设离线,则下⾯的指令就跳转到标号:
mov al, status
test al, 00100000b          ;测试位 5
jnz DeviceOffline
如果位 0、1 或 4 中任⼀位置 1,则下⾯的语句跳转到标号:
mov al, status
test al, 00010011b          ;测试位 0、1、4
jnz InputDataByte
如果是位 2、3 和 7 都置 1 使得跳转发⽣,则还需要 AND 和 CMP 指令:
mov al, status
and al,10001100b            ;屏蔽位 2、3 和 7
cmp al, 10001100b          ;所有位都置 1 ?
je ResetMachine              ;是:跳转
两个数中的较⼤数
下⾯的代码⽐较了 EAX 和 EBX 中的两个⽆符号整数,并且把其中较⼤的数送⼊ EDX:
mov    edx, eax                ;假设EAX存放较⼤的数
cmp eax, ebx                  ;若 EAX ≥ EBX
jae L1                              ;跳转到 L1
mov    edx, ebx                ;否则,将 EBX 的值送⼊ EDX
L1:                                      ;EDX 中存放的是较⼤的数
三个数中的最⼩数
下⾯的代码⽐较了分别存放于三个变量 VI、V2 和 V3 的⽆符号 16 位数值,并且把其中最⼩的数送⼊AX:
.data
V1 WORD ?
V2 WORD ?
V3 WORD ?
.code
mov    ax, V1    ;假设 V1 是最⼩值
cmp    ax, V2    ;如果 AX ≤ V2
jbe    L1            ;跳转到 L1
mov    ax, V2    ;否则,将 V2 送⼊ AX
LI:    cmp    ax, V3    ;如果 AX ≤ V3
c语言中文网汇编语言jbe L2                ;跳转到L2
mov    ax, V3    ;否则,将V3送⼊AX
L2 :
循环直到按下按键
下⾯的 32 位代码会持续循环,直到⽤户按下任意⼀个标准的字母数字键。如果输⼊缓冲区中当前没有按键,那么 Irvine32 库中的ReadKey 函数就会将零标 志位置1:
.data
char BYTE ?
.code
L1: mov eax, 10
call Delay              ;创建 10 毫秒的延迟;
call ReadKey        ;检查按键
jz L1                    ;如果没有按键则循环
mov char, AL      ;保存字符)
上述代码在循环中插⼊了⼀个 10 毫秒的延迟,以便 MS-Windows 有时间处理事件消息。如果省略这个延迟,那么按键可能被忽略。
【⽰例 1】:顺序搜索数组
常见的编程任务是在数组中搜索满⾜某些条件的数值。例如,下述程序就是在⼀个 16 位数组中寻第⼀个⾮零数值。如果到,则显⽰该数值;否则,就显⽰⼀条信息,以说明没有发现⾮零数值:
;扫描数组 (ArrayScan.asm)
;扫描数组寻第⼀个⾮零数值
INCLUDE Irvine32.inc
.data
intArray SWORD 0,0,0,0,1,20,35,-12,66,4,0
;intArray SWORD 1,0,0,0 ;候补测试数据
;intArray SWORD 0,0,0,0 ;候补测试数据
;intArray SWORD 0,0,0,1 ;候补测试数据
noneMsg BYTE "A non-zero value was not found",0
.code
main PROC
mov ebx,OFFSET intArray ;指向数组
mov ecx,LENGTHOF intArray ;循环计数器
L1: cmp WORD PTR [ebx],0 ;将数值与0⽐较
jnz found ;寻数值
add ebx,2 ;指向下⼀个元素
loop L1 ;继续循环
jmp notFound ;没有发现⾮零数值
found:
movsx eax,WORD PTR[ebx] ;送⼈EAX并进⾏符号扩展
call WriteInt
jmp quit
notFound:
mov edx,OFFSET noneMsg ;显⽰“没有发现”消息
call WriteString
quit:
call Crlf
exit
main ENDP
END main
本程序包含了可以替换的测试数据,它们已经被注释出来。取消这些注释⾏,就可 以⽤不同的数据配置来测试程序。
【⽰例 2】:简单字符串加密
XOR 指令有⼀个有趣的属性。如果⼀个整数 X 与 Y 进⾏ XOR,其结果再次与 Y 进⾏ XOR,则最后的结果就是 X:
( ( X  Y )  Y) = X
XOR 的可逆性为简单数据加密提供了⼀种⽅便的途径:明⽂消息转换成加密字符串,这个加密字符串被称为密⽂,加密⽅法是将该消息与被称为密钥的第三个字符串按位进⾏ XOR 操作。预期的查看者可以⽤密钥解密密⽂,从⽽⽣成原始的明⽂。
下⾯将演⽰⼀个使⽤对称加密的简单程序,即⽤同⼀个密钥既实现加密⼜实现解密的过程。运⾏时,下述步骤依序发⽣:
1) ⽤户输⼊明⽂。
2) 程序使⽤单字符密钥对明⽂加密,产⽣密⽂并显⽰在屏幕上。
3) 程序解密密⽂,产⽣初始明⽂并显⽰出来。
程序清单完整的程序清单如下所⽰:
;加密程序 (Encrypt.asm)
INCLUDE Irvine32.inc
KEY = 239 ;1-255之间的任⼀值
BUFMAX = 128 ;缓冲区的最⼤容量
.data
sPrompt BYTE "Enter the plain text:",0
sEncrypt BYTE "Cipher text",0
sDecrypt BYTE "Decrypted:",0
buffer BYTE BUFMAX+1 DUP(0)
bufSize DWORD ?
.code
main PROC
call InputTheString ;输⼊明⽂
call TranslateBuffer ;加密缓冲区
mov edx,OFFSET sEncrypt ;显⽰加密消息call DisplayMessage
call TranslateBuffer ;解密缓冲区
mov edx,OFFSET sDecrypt ;显⽰解密消息call DisplayMessage
exit
main ENDP
;-----------------------------------------InputTheString PROC
;
;提⽰⽤户输⼊⼀个纯⽂本字符串
;保存字符串和它的长度
;接收:⽆
;返回:⽆
;
-----------------------------------------
pushad ;保存32位寄存器
mov edx,OFFSET sPrompt ;显⽰提⽰
call WriteString
mov ecx,BUFMAX ;字符计数器最⼤值
mov edx,OFFSET buffer ;指向缓冲区
call ReadString ;输⼊字符串
mov bufSize,eax ;保存长度
call Crlf
popad
ret
InputTheString ENDP
;-----------------------------------------DisplayMessage PROC
;
;显⽰加密或解密消息
;接收:EDX指向消息
;返回:⽆
;-----------------------------------------pushad
call WriteString
mov edx,OFFSET buffer ;显⽰缓冲区call WriteString
call Crlf
call Crlf
popad
ret
DisplayMessage ENDP
;-----------------------------------------TranslateBuffer PROC
;
;字符串的每个字节都与密钥字节进⾏异或;实现转换
;接收:⽆
;返回:⽆
;-----------------------------------------pushad
mov ecx,bufSize ;循环计数器
mov esi,0 ;缓冲区索引初始值赋0
L1:
xor buffer[esi],KEY ;转换⼀个字节
inc esi ;指向下⼀个字节
loop L1
popad
ret
TranslateBuffer ENDP
END main

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。