博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ubuntu x86-64汇编(5) 控制指令
阅读量:7066 次
发布时间:2019-06-28

本文共 3108 字,大约阅读时间需要 10 分钟。

控制指令 Control Instructions

汇编的控制指令主要包含标签, 无条件跳转和有条件跳转几种

标签 Label

标签用于标记跳转的目的, 必须以字母开头, 后面跟着字母, 数字和下划线, 最后以冒号:结束

yasm里的标签是区分大小写的

无条件跳转 Unconditional Control Instructions

格式

jmp   

条件跳转 Conditional Control Instructions

条件跳转一般发生在一个比较指令之后, 比较的结果决定跳转是否执行. 比较指令的结果会存储在rFlag寄存器. 条件跳转要紧接着比较指令进行, 以免结果被其他指令修改.

比较指令的格式

cmp   
,

<op1> 和 <op2> 必须是同一尺寸且不能修改. 不能同时为内存. <op1>不能为立即数. 跳转指令je和jne对无符号数和有符号数同样适用. 但是其他的跳转指令会有区别, 适用于有符号数的有 jl, jle, jg, jge; 适用于无符号数的有 jb, jbe, ja, jae. 列表如下

je    

举例对于下面的判断语句

if (currNum > myMax)
  myMax = currNum;

;先定义变量currNum  dq  0myMax    dq  0; 代码为    mov   rax, qword [currNum]    cmp   rax, qword [myMax]    ;if currNum <= myMax    jle   notNewMax             ;   skip set new max    mov   qword [myMax], raxnotNewMax:

另一个例子

if (x != 0) {
    ans = x / y;
    errFlg = FALSE;
} else {
    ans = 0;
    errFlg = TRUE;
}

代码

TRUE   equ 1FALSE  equ 0x      dd  0y      dd  0ans    dd  0errFlg db  FALSE;;    cmp    dword [x], 0   ; if statement    je     doElse    mov    eax, dword [x]    cdq    idiv   dword [y]    mov    dword [ans], eax    mov    byte [errFlg], FALSE    jmp    skpElsedoElse:    mov    dword [ans], 0    mov    byte [errFlg], TRUEskpElse:

这个例子中因为是带符号数, 所以使用了idiv和cdq.

超出跳转范围 Jump Out Of Range

一般来讲, 条件跳转的目标标签要在128byte以内, 如果超出的话就会出现jump out-of-range错误. 但是无条件跳转是没有这个限制的. 可以用以下的方法解决这个问题

cmp   rcx, 0    je    endOfLoop    jmp   startOfLoopendOfLoop:

用je + jmp 代替 jne, 就避免了条件跳转的限制

枚举 Iteration

这个控制指令用于枚举或循环. 一个基本的循环由一个计数器和一个顶上或底下的判断和跳转组成. 例如

maxN  dq   30sum   dq   0; 下面的代码用于计算从1到maxN的奇数之和.mov   rcx, qword [maxN]   ; loop countermov   rax, 1              ; odd integer countersumLoop:    add   qword [sum], rax    ; sum current odd integer    add   rax, 2              ; set next odd integer    dec   rcx                 ; decrement loop counter    cmp   rcx, 0    jne   sumLoop

在这个例子中, rcx 用于循环的计数, rax用于存储当前循环的奇数, 用1初始化并每次加2.

另外我们也可以用loop指令来实现, 其格式如下, 执行时会递减rcx寄存器的值, 与0比较, 当不等于0时跳转(到开始处再次循环)
loop   <label>
之前的代码可以用loop改写为:

mov   rcx, qword [maxN]  ; loop countermov   rax, 1             ; odd integer countersumLoop:add   qword [sum], rax   ; sum current odd integeradd   rax, 2             ; set next odd integerloop  sumLoop

因为循环中会改写并检查rcx寄存器, 如果未初始化rcx寄存器, 将导致未知的循环次数. loop指令在编程中很有用, 但是受限于rcx寄存器. 如果需要多层的loop, 需要在循环内外进行rcx当前值的保存和恢复.

代码例子 平方数求和 Sum of Squares

;  Simple example program to compute the;  sum of squares from 1 to N.; **********************************************;  Data declarationssection   .data; ----;  Define constantsSUCCESS   equ  0       ; Successful operationSYS_exit  equ  60      ; call code for terminate;  Define Data.n         dd   10sumOfSquares  dq  0; *******************************************************section   .textglobal    _start_start:; ----;  Compute sum of squares from 1 to N.;  Approach:;    for (i=1; i

 

.

 

转载地址:http://bjxll.baihongyu.com/

你可能感兴趣的文章
Ubutu 12.04 LTS 安装iNode 后缺少libjpeg.so.62与libtiff.so.3解决方法--软连接问题
查看>>
简单组合逻辑电路的verilog实现(包括三态门、3-8译码器、8-3优先编码器、8bit奇偶校验器)...
查看>>
新浪微博Python SDK笔记——发微博(一)
查看>>
从零开始学C++之构造函数与析构函数(一):构造函数、析构函数、赋值与初始化、explicit关键字...
查看>>
SQL Server 表,记录 死锁解决办法
查看>>
Spring MVC
查看>>
Linux&shell 之Shell命令进阶
查看>>
浏览器内核Trident/Gecko/WebKit/Presto
查看>>
【转】一些图论、网络流入门题总结、汇总
查看>>
hdu 1531(差分约束)
查看>>
这个路口再次遇见你------单例模式在读取配置文件时的应用
查看>>
c# 操作excel 替代方案
查看>>
创建自定义的菜单与按钮
查看>>
tag标签数据库的设计
查看>>
C#操作sqlite数据库使用SQLiteParameter传递参数
查看>>
slick-pg v0.1.5 发布
查看>>
pygame系列_pygame安装
查看>>
Android开发探秘之二:导入存在的项目及其注意事项
查看>>
每日英语:In Digital Era, What Does 'Watching TV' Even Mean?
查看>>
聚合查询中的Group by
查看>>