【ARM 汇编基础速成6】ARM汇编之条件执行与分支

原文链接https://azeria-labs.com/arm-conditional-execution-and-branching-part-6/

条件执行

在之前讨论CPSR寄存器那部分时,我们大概提了一下条件执行这个词。条件执行用来控制程序执行跳转,或者满足条件下的特定指令的执行。相关条件在CPSR寄存器中描述。寄存器中的比特位的变化决定着不同的条件。比如说当我们比较两个数是否相同时,我们使用的Zero比特位(Z=1),因为这种情况下发生的运算是a-b=0。在这种情况下我们就满足了EQual的条件。如果第一个数更大些,我们就满足了更大的条件Grater Than或者相反的较小Lower Than。条件缩写都是英文首字母缩写,比如小于等于Lower Than(LE),大于等于Greater Equal(GE)等。

下面列表是各个条件的含义以及其检测的状态位(条件指令都是其英文含义的缩写,为了便于记忆不翻译了):

image

我们使用如下代码来实践条件执行相加指令:

.global main

main:
        mov     r0, #2     /* 初始化值 */
        cmp     r0, #3     /* 将R0和3相比做差,负数产生则N位置1 */
        addlt   r0, r0, #1 /* 如果小于等于3,则R0加一 */
        cmp     r0, #3     /* 将R0和3相比做差,零结果产生则Z位置一,N位置恢复为0 */
        addlt   r0, r0, #1 /* 如果小于等于3,则R0加一R0 IF it was determined that it is smaller (lower than) number 3 */
        bx      lr

上面代码段中的第一条CMP指令将N位置一同时也就指明了R0比3小。之后ADDLT指令在LT条件下执行,对应到CPSR寄存器的情况时V与N比特位不能相同。在执行第二条CMP前,R0=3。所以第二条置了Z位而消除了N位。所以ADDLT不会执行R0也不会被修改,最终程序结果是3。

Thumb模式中的条件执行

在指令集那篇文章中我们谈到了不同的指令集,对于Thumb中,其实也有条件执的(Thumb-2中有)。有些ARM处理器版本支持IT指令,允许在Thumb模式下条件执行最多四条指令。

相关引用:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABIJDIC.html

指令格式:Syntax: IT{x{y{z}}} cond

  • cond 代表在IT指令后第一条条件执行执行指令的需要满足的条件。
  • x 代表着第二条条件执行指令要满足的条件逻辑相同还是相反。
  • y 代表着第三条条件执行指令要满足的条件逻辑相同还是相反。
  • z 代表着第四条条件执行指令要满足的条件逻辑相同还是相反。

IT指令的含义是“IF-Then-(Else)”,跟这个形式类似的还有:

  • IT,If-Then,接下来的一条指令条件执行。
  • ITT,If-Then-Then,接下来的两条指令条件执行。
  • ITE,If-Then-Else,接下来的两条指令条件执行。
  • ITTE,If-Then-Then-Else,接下来的三条指令条件执行。
  • ITTEE,If-Then-Then-Else-Else,接下来的四条指令条件执行。

在IT块中的每一条条件执行指令必须是相同逻辑条件或者相反逻辑条件。比如说ITE指令,第一条和第二条指令必须使用相同的条件,而第三条必须是与前两条逻辑上相反的条件。这有一些ARM reference上的例子:

ITTE   NE           ; 后三条指令条件执行
ANDNE  R0, R0, R1   ; ANDNE不更新条件执行相关flags
ADDSNE R2, R2, #1   ; ADDSNE更新条件执行相关flags
MOVEQ  R2, R3       ; 条件执行的move

ITE    GT           ; 后两条指令条件执行
ADDGT  R1, R0, #55  ; GT条件满足时执行加
ADDLE  R1, R0, #48  ; GT条件不满足时执行加

ITTEE  EQ           ; 后两条指令条件执行
MOVEQ  R0, R1       ; 条件执行MOV
ADDEQ  R2, R2, #10  ; 条件执行ADD
ANDNE  R3, R3, #1   ; 条件执行AND
BNE.W  dloop        ; 分支指令只能在IT块的最后一条指令中使用

错误的格式:

IT     NE           ; 下一条指令条件执行
ADD    R0, R0, R1   ; 格式错误:没有条件指令

下图是条件指令后缀含义以及他们的逻辑相反指令:

image

让我们试试下面这段代码:

.syntax unified    @ 这很重要!
.text
.global _start

_start:
    .code 32
    add r3, pc, #1   @ R3=pc+1
    bx r3            @ 分支跳转到R3并且切换到Thumb模式下由于最低比特位为1

    .code 16         @ Thumb模式
    cmp r0, #10      
    ite eq           @ if R0 == 10
    addeq r1, #2     @ then R1 = R1 + 2
    addne r1, #3     @ else R1 = R1 + 3
    bkpt

.code32是指代码在ARM模式下执行。第一条机器码将PC地址加一并且送给了R3。在之后的跳转中就切换到了Thumb模式。这也是bxb指令的区别,前者会切换状态而后者不会。、

.code16是在Thumb模式下执行的代码。这段代码中的条件执行前提是R0等于10。ADDEQ指令代表了如果条件满足,那么就执行R1=R1+2,ADDNE代表了不满足时候的情况。

分支指令

分支指令(也叫分支跳转)允许我们在代码中跳转到别的段。当我们需要跳到一些函数上执行或者跳过一些代码块时很有用。这部分的最佳例子就是条件跳转IF以及循环。先来看看IF分支。

.global main

main:
        mov     r1, #2     /* 初始化 a */
        mov     r2, #3     /* 初始化 b */
        cmp     r1, r2     /* 比较谁更大些 */
        blt     r1_lower   /* 如果R2更大跳转到r1_lower */
        mov     r0, r1     /* 如果分支跳转没有发生,将R1的值放到到R0 */
        b       end        /* 跳转到结束 */
r1_lower:
        mov r0, r2         /* 将R2的值放到R0 */
        b end              /* 跳转到结束 */
end:
        bx lr              /* THE END */

上面的汇编代码的含义就是找到较大的数,类似的C伪代码是这样的:

int main() {
   int max = 0;
   int a = 2;
   int b = 3;
   if(a < b) {
    max = b;
   }
   else {
    max = a;
   }
   return max;
}

再来看看循环中的条件分支:

.global main

main:
        mov     r0, #0     /* 初始化 a */
loop:
        cmp     r0, #4     /* 检查 a==4 */
        beq     end        /* 如果是则结束 */
        add     r0, r0, #1 /* 如果不是则加1 */
        b loop             /* 重复循环 */
end:
        bx lr              /* THE END */

对应的C伪代码长这样子:

int main() {
   int a = 0;
   while(a < 4) {
   a= a+1;
   }
   return a;
}

B/BX/BLX

有三种类型的分支指令:

  • Branch(B)
    • 简单的跳转到一个函数
  • Branch link(BL)
    • 将下一条指令的入口(PC+4)保存到LR,跳转到函数
  • Branch exchange(BX) 以及 Branch link exchange(BLX)
    • 与B/BL相同,外加执行模式切换(ARM与Thumb)
    • 需要寄存器类型作为第一操作数:BX/BLX reg

BX/BLX指令被用来从ARM模式切换到Thumb模式。

.text
.global _start

_start:
     .code 32         @ ARM模式
     add r2, pc, #1   @ PC+1放到R2
     bx r2            @ 分支切换到R2

    .code 16          @ Thumb模式
     mov r0, #1

上面的代码将当前的PC值加1存放到了R2中(此时PC指向其后两条指令的偏移处),通过BX跳转到了寄存器指向的位置,由于最低有效位为1,所以切换到Thumb模式执行。下面GDB调试的动图说明了这一切。

image

条件分支指令

条件分支指令是指在满足某种特定条件下的跳转指令。指令模式是跳转指令后加上条件后缀。我们用BEQ来举例吧。下面这段汇编代码对一些值做了操作,然后依据比较结果进行条件分支跳转。

image

对应汇编代码如下:

.text
.global _start

_start:
   mov r0, #2
   mov r1, #2
   add r0, r0, r1
   cmp r0, #4
   beq func1
   add r1, #5
   b func2
func1:
   mov r1, r0
   bx  lr
func2:
   mov r0, r1
   bx  lr
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容