从零开始学ARM
上QQ阅读APP看书,第一时间看更新

3.2 数据处理指令

3.2.1 mov指令

(1)mov指令

mov指令表示如下。

mov{条件}{S} 目的寄存器,源操作数

mov指令用于将一个立即数从一个寄存器或能被移位的寄存器加载到目的寄存器中。其中S项决定指令的操作是否影响CPSR中条件标志位的值,当没有S项时,不更新CPSR中条件标志位的值。

指令示例如下。

mov r0,#0x1         ;将立即数0x1传送到寄存器R0中
mov r1,r0           ;将寄存器R0的值传送到寄存器R1中
mov pc,r14          ;将寄存器R14的值传送到PC中,常用于子程序返回
mov r1,r0,LSL#3    ;将寄存器R0的值左移3位后传送到寄存器R1中

注意:

指令不区分大小写,程序句尾“;”“//”“@”之后的内容为注释,在“/*”和“*/”之间的内容为注释。

(2)什么是立即数

在回答这个问题之前,我们先看下面这条指令。

mov r0,#0xfff

将其编译后会有以下报错。

Build target ‘Target 1’
assembling S3C2440.s...
S3C2440.s(5): error: A1510E: Immediate 0x00000FFF cannot be represented by 0-255 and a rotation
S3C2440.s:   5 00000000 MOV R0,#0xfff
S3C2440.s: 1 Error, 0 Warnings
Target not created

要想解决这个问题,我们需要了解什么是立即数。立即数是由数据(0~255)循环右移偶数位生成的,判断规则归纳如下。

① 把数据转换成二进制形式,并从低位到高位将其分成4位1组,最高位一组不够4位的,在最高位前补0。

② 数其中1的个数,如果1大于8个,则该数据肯定不是立即数,如果1小于等于8个则进行下面步骤。

③ 如果数据中有连续的、大于等于24个的0,循环左移2的倍数位,使高位全为0。

④ 找到此时数据中1的最高位,去掉前面最大偶数个0。

⑤ 找到最低位的1,去掉其后面最大偶数个0。

⑥ 数剩下的位数,如果小于等于8位,那么这个数就是立即数,反之就不是立即数。

上述示例中的数据是0xfff,先将其转换为二进制形式。

0000 0000 0000 0000 0000 1111 1111 1111

按照上述规则,最终操作结果如下。

1111 1111 1111

可以看到剩余的位数大于8个,所以该数不是立即数。

(3)mov机器码

为什么立即数会有如上限定?我们需要从mov指令的机器码来说起。首先让我们执行如下程序。

    area Example,code,readonly;声明程序段Example
    entry;程序入口
start
    ;此处为测试程序,添加在以下位置即可,之后不再介绍完整程序
    mov r1,#0x80000001
over
    end

使用鼠标指针单击操作界面的debug按钮,查看对应的机器码,如图3-1所示。

图3-1 机器码

得到指令“mov r1,#0x80000001”的机器码是E3A01106(十六进制)。mov指令机器码格式如图3-2所示。

图3-2 mov指令机器码格式

根据mov指令格式,我们分析各个位域的含义,如表3-2所示。

表3-2 mov指令机器码各个位域含义

立即数0x80000001的二进制数如下。

1000 0000 0000 0000 0000 0000 0000 0001

将数据循环左移2位后得到以下结果。

00 0000 0000 0000 0000 0000 0000 0001 10

因此,偏移的值为1(2/2),操作数的值为0000 0110。读者可以随机找一些整数,判断其是否是立即数。