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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值