精华内容
下载资源
问答
  • 16位汇编指令

    千次阅读 2017-05-22 21:00:24
    汇编语言特点:与机器相关,执行效率高,调试复杂 汇编语言优缺点:汇编语言和高级语言混合编写,互补 数据表示类型:二进制B,八进制Q,十进制D,十六进制H BCD编码:用二进制来表示十进制数 CPU资源和存储器:通用...

    汇编语言特点:与机器相关,执行效率高,调试复杂

    汇编语言优缺点:汇编语言和高级语言混合编写,互补

    数据表示类型:二进制B,八进制Q,十进制D,十六进制H

    BCD编码:用二进制来表示十进制数

    CPU资源和存储器:通用寄存器,标志寄存器,指令寄存器

    EAX,累加

    ECX,循环计数

    EDX,数据寄存器

    EBX,基址寄存器

    ESP,栈顶

    EBP,栈底

    ESI,扩展源指针

    EDI,扩展目的指针

    EIP,指令指针

    SI(16位),变址寄存器,常用于存储器寻址时提供地址,源操作数指针

    DI(16位),变址寄存器,常用于存储器寻址时提供地址,目的操作数指针

    Flag寄存器

    15

    14

    13

    12

    11

    10

    9

    8

    7

    6

    5

    4

    3

    2

    1

    0

     

     

     

     

    OF

    DF

    IF

    TF

    SF

    ZF

     

    AF

     

    PF

     

    CF

     

     

     

     

    溢出

    方向

    中断

    陷阱

    符号

     

    辅助

     

    奇偶

     

    进位

    Debug状态

    真假

    OV/NV

    DN/UP

    EI/DI

     

    NG/PL

    ZR/NZ

     

    AC/NA

     

    PE/PO

     

    CY/NC

    进位CF,CF=1,运算结果表示有进位或者借位

    零标志ZF,ZF=1,表示结果为0

    符号标志SF,SF=1,运算结果最高位为1

    奇偶标志PF,PF=1,运算结果最低8位1的个数为0或者偶数(奇)

    溢出标志OF,OF=1,算数运算结果有溢出

    辅助进位AF,AF=1,运算时有进位或借位

    方向标志DF,DF=1,地址自动减少,用于串操作,控制地址变化方向

    中断标志IF,IF=1,允许中断,用于控制外部可屏蔽中断是否可处理

    陷阱标志TF,TF=1,处理器处于单步执行指令(处理器每执行一条指令便产生一个内部中断,可以对程序进行单步调试)

    16位汇编物理地址与逻辑地址转换:逻辑地址<< 4位 + 偏移 = 物理地址(可以有多个逻辑地址)

    CS(代码段),表示代码段的起始地址

    SS(堆栈段),表示堆栈段的起始地址

    DS(数据段),表示数据段的起始地址

    ES(附加段),表示附加段的起始地址,附加段是数据段,用于数据保存,串操作指令将附加段作为其目的操作数的存放区域

    段前缀CS:  ;使用代码段

    段前缀SS:  ;使用栈段

    段前缀DS:  ;使用数据段

    段前缀ES:  ;使用附加段

    默认访问DS,使用BP则访问主存(SS)

    1M最多可分64K个段,最少能分16个段

    8086有8个8位通用寄存器(al,ah…),8个16位通用寄存器(ax,bx…),6个状态标志(CF,ZF,SF,PF,OF,AF)和3个控制标志(DF,IF,TF),4个段寄存器,4种逻辑段,4个段前缀指令

     

    立即数寻址,mov ah,0x01

    寄存器寻址,mov ah,[bh]

    直接寻址,mov AX,ES:[2000H]

    寄存器间接寻址,mov AX,[SI]

    寄存器相对寻址,mov AX,[DI+05]

    基址变址寻址,mov AX,[BX(BP)+SI]

    相对基址变址寻址,mov AX,[BX+SI+05]

     

    段内转移也称近转移(near ptr)

    段内转移也称短转移(short)

    段间转移也称远转移(far ptr)

     

    8086汇编指令

    [ASM]8088汇编指令

    一、数据传输指令

    ───────────────────────────────────────

      它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.

      1. 通用数据传送指令.

        MOV 传送字或字节.

        MOVSX 先符号扩展,再传送.

        MOVZX 先零扩展,再传送.

        PUSH  把字压入堆栈.

        POP  把字弹出堆栈.

        PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.

        POPA  把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.

        PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.

        POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.

        BSWAP 交换32位寄存器里字节的顺序

        XCHG  交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数)

        CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX )

        XADD  先交换再累加.( 结果在第一个操作数里 )

        XLAT  字节查表转换.

            ── BX 指向一张 256 字节的表的起点, AL 为表的索引值 (0-255,即

            0-FFH); 返回 AL 为查表结果. ( [BX+AL]->AL )

     

      2. 输入输出端口传送指令.

        IN   I/O端口输入. ( 语法: IN 累加器, )

        OUT   I/O端口输出. ( 语法: OUT ,累加器 )

        输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时, 其范围是 0-65535.

        

      3. 目的地址传送指令.

        LEA  装入有效地址.

        例: LEA DX,string ;把偏移地址存到DX.

        

        LDS  传送目标指针,把指针内容装入DS.

        例: LDS SI,string ;把段地址:偏移地址存到DS:SI.

        

        LES  传送目标指针,把指针内容装入ES.

        例: LES DI,string ;把段地址:偏移地址存到ES:DI.

        

        LFS  传送目标指针,把指针内容装入FS.

        例: LFS DI,string ;把段地址:偏移地址存到FS:DI.

        

        LGS  传送目标指针,把指针内容装入GS.

        例: LGS DI,string ;把段地址:偏移地址存到GS:DI.

        

        LSS  传送目标指针,把指针内容装入SS.

        例: LSS DI,string ;把段地址:偏移地址存到SS:DI.

        

      4. 标志传送指令.

        LAHF  标志寄存器传送,把标志装入AH.

        SAHF  标志寄存器传送,把AH内容装入标志寄存器.

        PUSHF 标志入栈.

        POPF  标志出栈.

        PUSHD  32位标志入栈.

        POPD  32位标志出栈.

     

    二、算术运算指令

    ───────────────────────────────────────

        ADD  加法.

        ADC  带进位加法.

        INC  加 1.

        AAA  加法的ASCII码调整.

        DAA  加法的十进制调整.

        SUB  减法.

        SBB  带借位减法.

        DEC  减 1.

        NEC  求反(以 0 减之).

        CMP  比较.(两操作数作减法,仅修改标志位,不回送结果).

        AAS  减法的ASCII码调整.

        DAS  减法的十进制调整.

        MUL  无符号乘法.

        IMUL  整数乘法.

        以上两条,结果回送AH和AL(字节运算),或DX和AX(字运算).

        

        AAM  乘法的ASCII码调整.

        DIV  无符号除法.

        IDIV  整数除法.

        以上两条,结果回送:

        商回送AL,余数回送AH, (字节运算); 或商回送AX,余数回送DX, (字运算).

        

        AAD  除法的ASCII码调整.

        CBW  字节转换为字. (把AL中字节的符号扩展到AH中去)

        CWD  字转换为双字. (把AX中的字的符号扩展到DX中去)

        CWDE  字转换为双字. (把AX中的字符号扩展到EAX中去)

        CDQ  双字扩展.   (把EAX中的字的符号扩展到EDX中去)

     

    三、逻辑运算指令

    ───────────────────────────────────────

        AND  与运算.

        OR  或运算.

        XOR  异或运算.

        NOT  取反.

        TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).

        SHL  逻辑左移.

        SAL  算术左移.(=SHL)

        SHR  逻辑右移.

        SAR  算术右移.(=SHR)

        ROL  循环左移.

        ROR  循环右移.

        RCL  通过进位的循环左移.

        RCR  通过进位的循环右移.

        以上八种移位指令,其移位次数可达255次.

        移位一次时, 可直接用操作码. 如 SHL AX,1.

        移位>1次时, 则由寄存器CL给出移位次数.

        如   MOV CL,04

            SHL AX,CL

     

    四、串指令

    ───────────────────────────────────────

        DS:SI 源串段寄存器 :源串变址.

        ES:DI 目标串段寄存器:目标串变址.

        CX   重复次数计数器.

        

        AL/AX 扫描值.

        D标志  0表示重复操作中SI和DI应自动增量; 1表示应自动减量.

        Z标志 用来控制扫描或比较操作的结束.

        

        MOVS  串传送.

        ( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )

        

        CMPS  串比较.

        ( CMPSB 比较字符. CMPSW 比较字. )

        

        SCAS  串扫描.

        把AL或AX的内容与目标串作比较,比较结果反映在标志位.

        

        LODS  装入串.

        把源串中的元素(字或字节)逐一装入AL或AX中.

        ( LODSB 传送字符.  LODSW 传送字.  LODSD 传送双字. )

        

        STOS  保存串.

        是LODS的逆过程.

        

        REP      当CX/ECX<>0时重复.

        REPE/REPZ   当ZF=1或比较结果相等,且CX/ECX<>0时重复.

        REPNE/REPNZ  当ZF=0或比较结果不相等,且CX/ECX<>0时重复.

        REPC      当CF=1且CX/ECX<>0时重复.

        REPNC     当CF=0且CX/ECX<>0时重复.

     

    五、程序转移指令

    ───────────────────────────────────────

       1>无条件转移指令 (长转移)

        JMP      无条件转移指令

        CALL      过程调用

        RET/RETF    过程返回.

        

       2>条件转移指令 (短转移,-128到+127的距离内)

        ( 当且仅当(SF XOR OF)=1时,OP1  

        JA/JNBE    不小于或不等于时转移.

        JAE/JNB    大于或等于转移.

        JB/JNAE    小于转移.

        JBE/JNA    小于或等于转移.

        以上四条,测试无符号整数运算的结果(标志C和Z).

        

        JG/JNLE 大于转移.

        JGE/JNL 大于或等于转移.

        JL/JNGE 小于转移.

        JLE/JNG 小于或等于转移.

        以上四条,测试带符号整数运算的结果(标志S,O和Z).

        

        JE/JZ     等于转移.

        JNE/JNZ    不等于时转移.

        JC       有进位时转移.

        JNC      无进位时转移.

        JNO      不溢出时转移.

        JNP/JPO    奇偶性为奇数时转移.

        JNS      符号位为 "0" 时转移.

        JO       溢出转移.

        JP/JPE     奇偶性为偶数时转移.

        JS       符号位为 "1" 时转移.

        

      3>循环控制指令(短转移)

        LOOP      CX不为零时循环.

        LOOPE/LOOPZ   CX不为零且标志Z=1时循环.

        LOOPNE/LOOPNZ  CX不为零且标志Z=0时循环.

        JCXZ      CX为零时转移.

        JECXZ      ECX为零时转移.

        

      4>中断指令

        INT      中断指令

        INTO      溢出中断

        IRET      中断返回

        

      5>处理器控制指令

        HLT      处理器暂停, 直到出现中断或复位信号才继续.

        WAIT      当芯片引线TEST为高电平时使CPU进入等待状态.

        ESC      转换到外处理器.

        LOCK      封锁总线.

        NOP      空操作.

        STC      置进位标志位.

        CLC      清进位标志位.

        CMC      进位标志取反.

        STD      置方向标志位.

        CLD      清方向标志位.

        STI      置中断允许位.

        CLI      清中断允许位.

     

    六、伪指令

    ───────────────────────────────────────

        DW       定义字(2字节).

        PROC      定义过程.

        ENDP      过程结束.

        SEGMENT    定义段.

        ASSUME     建立段寄存器寻址.

        ENDS      段结束.

        END      程序结束. 

    展开全文
  • 指令编码及拓展

    2020-01-07 18:57:30
    机器采用16位字长指令, (1)若采用定长操作码,地址码5位,现已定义60条二地址指令,那么一地址指令最多多少条? (2)修改(1)条件为不定长操作码,其余不变,答案如何? 1: 二地址指令格式如下 op...

    某机器采用16位字长指令,

    (1)若采用定长操作码,地址码5位,现已定义60条二地址指令,那么一地址指令最多多少条?   

    (2)修改(1)条件为不定长操作码,其余不变,答案如何?

     

    1:

    二地址指令格式如下

    op操作码6位

    地址码1:5位

    地址码2:5位

    万变指令格式不会变,定长操作码,即操作码定死为6

    又二地址指令有60条

    6位总共能编码2^6=64条

    一地址指令=总编码数-二地址指令条数=64-60=4条

     

    2:

    指令格式还是不变如上图

    但是操作码不定死6了,它可以变动,拓展几位可以编码更多的指令

    首先,已经占用了60条,还剩4种编码即如下四种情况:

    op操作码6位(前面4个1)

    00

    空,可利用

    地址码1:5位

    op操作码6位(前面4个1)

    01

    空,可利用

    地址码1:5位

    op操作码6位(前面4个1)

    10

    空,可利用

    地址码1:5位

    op操作码6位(前面4个1)

    11

    空,可利用

    地址码1:5位

    这四种情况即用2位可以表示,那么这两位可以作为拓展码(拓展标志)

    当发现有拓展标志的时候,后面两个地址码只用了一个,那么空出来的那5位地址码可以用来编码一地址指令

    即一指令=4种情况*2^5=4*32=128条

    展开全文
  • 机器指令字长为16位 只有单地址指令和双地址指令两类,不考虑零地址指令 明确这两点后,我们还需要知道一个知识点,就是哈夫曼编码,哈夫曼编码的主要思想就是短码不能是长码的前缀。 接下来就是对这道题的理解: ...

    题目:某机指令字长16位,共有单地址指令和双地址指令两类,若每个地址字段均为5位,且双地址指令已用了X条,问单地址指令最多可以有多少条?

    明确两点:

    • 机器指令字长为16位
    • 只有单地址指令和双地址指令两类,不考虑零地址指令

    明确这两点后,我们还需要知道一个知识点,就是哈夫曼编码,哈夫曼编码的主要思想就是短码不能是长码的前缀。
    接下来就是对这道题的理解:
    我们知道每个地址字段是5位,那么双地址指令中有10位是地址码,剩余6位是操作码,那么我们就能知道这6位操作码最多能后实现2^6 个指令,也就是从000000-111111,这里说双地址已经用了X条,也就是说000000-111111这些编码里面已经有X被用掉了,根据短码不能是长码的前缀的要求,也就是说单地址指令的表示中不能出现这X条的编码,那么在前单地址指令的前6位操作码中可用的只剩下(64-X)条,也就是2^6 -X条指令。此外单地址指令有5位地址码,11位操作码,前面的6位可能的编码情况已经确定,那么接下来就是后面5位的编码情况,只要满足了前面的6位编码不是双地址的指令编码就可以,后面的5位就可以随便,也就是有2^5 个编码,所以单地址指令最多有(2^6 -X)* 2^5 条。

    补充题目:某处理器的指令字长为16位,有二地址指令、一地址指令和零地址指令三种,每个地址字段的长度均为6 位。如果二地址指令有15条,一地址指令和零地址指令的条数基本相等,那么一地址指令和零地址指令各有多少条?试为这三种指令分配操作码。

    这一道题,相比于上一道题多了零地址指令,不过思想都是一样的。
    双地址指令的结构:4位操作码,6位地址码A,6位地址码B;
    单地址指令的结构:10位操作码,6位地址码;
    零地址指令的结构:16位操作码。
    指令分配过程中必须满足的条件:短码不能是长码的前缀。
    这里设单地址指令有X条,由于单地址指令的前4位操作码已经被双地址指令用了15条,那么可用的还有2^4 -15,也就是一条,那么后面6位操作码中应该有X中编码方式(因为我们前面已经假设单地址指令有X条,根据(2^4 -15)* 后六位操作码编码方式 = X),单地址指令确定后,我们再来看零地址指令,由于零地址指令没有地址码,16位都是操作码,并且我们知道零地址指令的16位操作码中的前10位操作码编码不能是双地址指令的前缀也不能是单地址指令的前缀,我们根据前面的分析可知,零地址指令还可以有(2^6 - X)* 2^6 种编码方式,由于单地址指令跟零地址指令的条数基本相等,那么我们知道
    X\approx(2^6 - X ) * 2^6 ,那么我们可以计算出X=63。
    这道题的答案就出来啦!

    展开全文
  • 第七章 ARM 反汇编基础(六)(Thumb...16 Thumb 指令编码 16 Thumb 指令格式解析 32 Thumb 指令编码 32 Thumb 指令格式解析 Thumb 汇编指令集 作为 ARM 指令集的一个子集,针对代码密度问题提出,具有 ...

     

    第七章 ARM 反汇编基础(六)(Thumb 汇编指令集)

    zlmm741 2020-03-30 21:57:49  749  收藏 3
    分类专栏: 《Android 软件安全权威指南》学习笔记 文章标签: android ubuntu 安全
    版权
    文章目录
    Thumb 汇编指令集
    16 位 Thumb 指令编码
    16 位 Thumb 指令格式解析
    32 位 Thumb 指令编码
    32 位 Thumb 指令格式解析
    Thumb 汇编指令集
    作为 ARM 指令集的一个子集,针对代码密度问题提出,具有 16 位的指令宽度
    与 ARM 指令的 32 位宽度相比,Thumb 指令集在保留 32 位宽度优势的同时大大节省了系统的存储空间
    Thumb 不是一个完整的体系结构,包含的指令集十分有限,常与 ARM 指令搭配使用
    第一代 Thumb 指令集更新到 ARMv6T2 后,引入了第二代 Thumb 指令集,使用与 ARM 指令相同的 32 位指令,不仅性能与 32 位 ARM 指令相当,还保留了第一代指令的简洁特性
    Thumb 指令和 ARM 指令除了长度不同,寄存器的使用也不同。Thumb 指令集中,R11 ~ R15 寄存器使用 FP、IP、SP、LR、PC 等命名,新的命名方式直接在名称上体现了寄存器的用途,使用上也有限制和差异(相较 ARM 指令)
    第一代 Thumb 指令的宽度只有 16 位,在地址读取范围上比 ARM 指令小很多,在进行一些大范围的指令跳转操作时只能切换到 ARM 模式,执行 ARM 指令
    16 位 Thumb 指令编码
    16 位的 Thumb 指令称第一代 Thumb 指令
    格式:

    可看到,第一代 Thumb 指令设计十分简洁,只用了一个 bits[15:10] 的 Opcode 域来确定指令及其分类
    第一代 Thumb 指令的所有指令及分类方法(Opcode 域中的 x 表示取值可为 0 或 1):
    Opcode    指令或指令类别
    00xxxx    移位、加、减、移动与比较指令
    010000    数据处理指令
    010001    特殊数据指令,分支与交换指令
    01001x    常量池加载指令,LDR 指令
    0101xx    加载/存储单个数据指令
    011xxx    加载/存储单个数据指令
    100xxx    加载/存储单个数据指令
    10100x    相对于 PC 寄存器的加法指令,ADR 指令
    10101x    相对于 SP 寄存器的加法指令,ADD 指令
    1011xx    杂项指令
    11000x    多寄存器存储指令,STM、STMIA、STMEA 指令
    11001x    多寄存器加载指令,LDM、LDMIA、LDMFD 指令
    1101xx    条件分支与中断指令
    11100x    无条件分支指令,B 指令
    在用 Android NDK 编译代码时,若想默认生成 Thumb 指令而非 ARM 指令,可在编译代码时指定 -mthumb 参数:
    $CC app.c -fPIE -S -mthumb -march=armv5te
    在生成的汇编代码中,子程序会的开头会自动添加 .thumb_func 伪指令
    16 位 Thumb 指令格式解析
    以十六进制值 0x4611 为例,分析其指令编码,找出其对应的 Thumb 指令
    用计算器查看其二进制编码:

    bits[15:10] 的 Opcode 域的值为 0b010001,对应指令分类中的特殊数据指令、分支与交换指令系列,具体的指令格式:

    bits[9:6] 的 Opcode 域的值为 0b1000,对应 MOV 低位寄存器指令,格式:


    MOV<c> <Rd>, <Rm>
    对应的指令的位域分布:

    指令伪代码描述:
    d = UInt(D:Rd);
    m = UInt(Rm);
    setflags = FALSE;
    if d == 15 && InitBlock() && !LastInitBlock()
        then UNPREDICTABLE;
    1
    2
    3
    4
    5
    d 等于 15 被定义为不可预知行为,所以,bits[7:3] 不能为 0b10101。Rm 寄存器为源寄存器,取值为 0b0010(表示 R2 寄存器)。Rd 为目标寄存器,取值为 0b001(表示 R1 寄存器)
    综上,这条指令的完整格式为 MOV R1, R2
    验证(此处为大端序):

    32 位 Thumb 指令编码
    32 位的 Thumb 指令又称 Thumb-2 指令
    Thumb 指令分为 16 位和 32 位两个版本,如何区分?若一段汇编代码中包含 Thumb、Thumb-2、ARM 三种类型的指令,处理器在执行代码时要用什么方法正确区分它们?Thumb 与 ARM 间的切换采用 CPSR 的 T 标志位,在执行 BX、BLX 指令时,处理器模式的切换依赖于执行地址的最低位(bit[0])。Thumb 与 Thumb-2 间的指令识别依赖于指令编码格式的设计准则
    ARM 规定:一条 Thumb 指令的 bits[15:11](高五位)有如下取值时,表示这是一条 Thumb-2 指令:
    0b11101:高三位全为 1,当第四位为 0 时,第五位必须为 1(因为 0b11100 在 16 位 Thumb 指令中被无条件分支指令占用)
    0b11110:高四位全为 1
    0b11111:高四位全为 1
    32 位的 Thumb 指令用两个 16 位表示:

    第一个 16 位的高三位永远是 1,然后依次是第一个 16 位的 bits[12:11] 的 op1 域、bits[10:4] 的 op2 域,及第二个 16 位的 bit[15] 的 op 域,它们组合后的不同值表示不同的 32 位 Thumb 指令。完整的指令类别定义:
    op1    op2         op    指令类别
    01    00xx0xx        多寄存器加载与存储指令
    01    00xx1xx        寄存器加载与存储指令
    01    01xxxxx        数据处理(寄存器移位)指令
    01    1xxxxxx        协处理器指令
    10    x0xxxxx    0    数据处理(立即数修改)指令
    10    x1xxxxx    0    数据处理(二进制立即数)指令
    10        1    分支与杂项指令
    11    000xxx0        存储单数据指令
    11    001xxx0        高级 SIMD 与结构化加载存储指令
    11    00xx001        字节加载指令
    11    00xx011        半字加载指令
    11    00xx101        字加载指令
    11    00xx111        未定义
    11    010xxxx        数据处理(寄存器)指令
    11    0110xxx        乘法、乘积与绝对差指令
    11    0111xxx        长型乘法、长型乘积与除法指令
    11    1xxxxxx        协处理器指令
    可看出,32 位的 Thumb 指令比 16 位的丰富很多。在用 armeabiv7-a 及以上版本的指令集时,要想编译生成 32 位的 Thumb 代码,要指定 -mthumb 参数。在生成的代码中,编译器会根据场景选择用 16 位或 32 位指令,结果通常是在一段 Thumb 指令的汇编代码中同时包含 16 位与 32 位的 Thumb 指令
    执行如下命令,可为 app2.c 生成 Thumb-2 汇编指令:

    用 IDA Pro 打开生成的 app2,定位到 main() 处,会看到生成的代码中有 MOVT.W、LDRD.W 这种带 .W 后缀的指令,这种指令格式 Thumb-2 特有

    32 位 Thumb 指令格式解析
    以十六进制数 0xF0814100 为例,分析其指令编码,找到其对应的 Thumb-2 指令(自己添加0xF0814100是机器码,下面例子是转为汇编指令的过程2021.4.2)
    用计算器查看其二进制编码:

    bits[12:11] 的 op1 域值为 0b10,bits[10:4] 的 op2 域值为 0b0001000,对应的指令类别为数据处理(立即数修改)指令。其指令格式:

    第一个 16 位的 bits[8:5] 的 op 域值为 0b0100,第二个 16 位的 bits[11:8] 的 Rd 域值为 0b0001,对应的指令为 EOR(立即数指令)。EOR 指令格式:

    EOR<S><c> <Rd>, <Rn>, #<const>
    对应的指令二进制位域分布:

    可看到,此指令的格式较复杂。Rd 的值为 0b0001,表示 R1 寄存器;Rn 的值为 0b001,表示也是 R1 寄存器。这里重要的是如何计算 const 的值
    EOR 的伪代码描述:
    if Rd == '1111' && S == '1'
        then SEE TEQ (immediate);
    d = UInt(Rd);
    n = UInt(Rn);
    setflags = (S == '1');
    (imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C);
    if BadReg(n)
        then UNPREDICTABLE;
    1
    2
    3
    4
    5
    6
    7
    8
    imm32 的值就是 const 的值,它的计算由 ThumbExpandImm_C() 完成。传入的参数有两个,一个是由 i、imm3、imm8 三个域组成的 12 位的值,另一个是 APSR 的 C 标志。这里主要看前一个参数的取值。i 的值为 0,imm3 域为第二个 16 位的 bits[14:12],值为 0b100,imm8 域为第二个 16 位的 bits[7:0],值为 0b00000000,合起来就是 0b010000000000
    ARM 指令参考手册中,ThumbExpandImm_C() 的伪代码:
    // ThumbExpandImm_C()
    // ==================

    (bits(32), bit) ThumbExpandImm_C(bits(12) imm12, bit carry_in)

    if imm12<11:10> == '00' then
        case imm12<9:8> of
            when '00'
                imm32 = ZeroExtend(imm12<7:0>, 32);
            when '01'
                if imm12<7:0> == '00000000'
                    then UNPREDICTABLE;
                imm32 = '00000000' : imm12<7:0> : '00000000' : imm12<7:0>;
            when '10'
                if imm12<7:0> == '00000000'
                    then UNPREDICTABLE;
                imm32 = imm12<7:0> : '00000000' : imm12<7:0> : '00000000';
            when '11'
                if imm12<7:0> == '00000000'
                    then UNPREDICTABLE;
                imm32 = imm12<7:0> : imm12<7:0> : imm12<7:0> : imm12<7:0>;
        carry_out = carry_in;
    else
        unrotated_value = ZeroExtend('1':imm12<6:0>, 32);
        (imm32, carry_out) = ROR_C(unrotated_value, UInt(imm12<11:7>));
    return (imm32, carry_out);
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    根据 imm12 的高两位判断,其值为 0b01,会执行 else 语句处的指令,ZeroExtend() 将 1 与 imm12 的低七位组合后,扩展到 32 位,即 unrotated_value 的值是一个 32 位的整数且只有第八位为 1,其他位均为 0。接着,ROR_C() 进行循环右移,伪代码:
    // ROR_C()
    // =======

    (bits(N), bit) ROR_C(bits(N) x, integer shift)
        assert shift != 0;
        m = shift MOD N;
        result = LSR(x, m) OR LSL(x, N-m);
        carry_out = result<N-1>;
        return (result, carry_out);
    1
    2
    3
    4
    5
    6
    7
    8
    9
    将 unrotated_value 的值循环右移 shift 位。shift 的值为 imm12 的高五位,为 0b01000,即 8。循环右移 8 位后,第八位的 1 到了最高位(第三十一位),其他全部为 0,结果为 0x80000000
    综上,0xF0814100 对应的 Thumb-2 指令为 EOR R1, R1, #0x80000000
    rasm2 命令不支持对 Thumb-2 指令数据进行汇编,但支持对 Thumb-2 指令反汇编,可执行如下命令验证上述结果:

    上述举例是机器码反汇编转为汇编指令

    ubuntu是linux系统下的反汇编工具

    自己添加汇编指令eor  r1,r1,0x80000000 转机器码81 F0 00 41 ,体会立即数转换过程

    之所以传入 0x81F00041 而非 0xF0814100,是因为 Thumb-2 虽是 32 位,但读取和解析仍以 16 位进行,对应的小端字节序的数据与 32 位的情况有所不同
    ————————————————
    版权声明:本文为CSDN博主「zlmm741」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/zlmm741/article/details/105209734

     

    展开全文
  • 80X86寻址方式与常见汇编指令

    千次阅读 2016-01-25 21:31:08
     操作码:执行操作,用一个唯一的助记符表示,对应着机器指令的一个二进制编码;  操作数:操作对象,可以是数值,寄存器或存储器地址;  助记符格式:  操作码 目的操作数,源操作数;注释  指令操作数:  r8...
  • 机器语言

    2010-08-25 21:18:00
    机器语言是直接用二进制代码指令表达的计算机语言,指令是用0和1组成的一串代码,它们有一定的位数,并分成若干段,各段的编码表示不同的含义,例如某台计算机字长为16位,即有 16个二进制数组成一条指令或其它信息...
  • 先读题目,某机器指令字长为16位,主存按字节编址。读到这里应该反应,一条指令应该占有两个字节。每取一字节,PC自动加一。所以是,每取一条指令,那么PC是加2.所以,取地址后,PC的值为 PC+2,也就是2000H。...
  • 由于计算机内部只能接受...机器语言是直接用二进制代码指令表达的计算机语言,指令是用0和1组成的一串代码,它们有一定的位数,并分成若干段,各段的编码表示不同的含义,例如某台计算机字长为16位,即有16个二进制...
  • 直接用二进制代码指令表达的计算机语言,指令是用0和1组成的一串代码,它们有一定的位数,并分成若干段,各段的编码表示不同的含义,例如某台计算机字长为16位,即有 16个二进制数组成一条指令或其它信息。...
  • chap3: 程序的机器级表示

    千次阅读 2011-06-24 22:06:00
    3.2、程序编码 1、对机器级编程而言,两种抽象尤为重要:1)指令集体系结构(Instruction set architecture,ISA;2)虚拟地址; 2、程序存储器包含:可执行代码,OS的一些信息,运行时栈,堆; 3.3、数据格式:...
  • 假设:假设某机机器字长为16位指令字长等于机器字长。 机器指令系统要求完成32种操作,支持8种寻址方式。ALU乘法部件采用补码Booth算法一位乘。要求: 1. 设计该主机的指令系统格式,并给出ADD, STA, OUT, ...
  • Chapter 2 信息的表示和处理 计算机用有限数量的位来对应一个数字...所谓的16位32位64位系统是由cpu决定的,由机器指令的寻址、寄存器位数决定的int只是语言定义里面的一个关键字,只对compiler可见,compl
  • 机器语言机器语言是直接用二进制代码指令表达的计算机语言,指令是用0和1组成的一串代码,它们有一定的位数,并分成若干段,各段的编码表示不同的含义,例如某台计算机字长为16位,即有16个二进制数组成一条指令或...
  • 信息学奥林匹克竞赛-编程语言

    千次阅读 2015-11-17 13:15:53
    机器语言:是直接用二进制代码指令表达的计算机语言,指令是用0和1组成的一串代码,它们有一定的位数,并分成若干段,各段的编码表示不同的含义,例如某台计算机字长为16位,即有16个二进制数组成一条指令或其它信息...
  • 主流编程语言简介

    千次阅读 2015-12-03 14:49:34
     机器语言:是直接用二进制代码指令表达的计算机语言,指令是用0和1组成的一串代码,它们有一定的位数,并分成若干段,各段的编码表示不同的含义,例如某台计算机字长为16位,即有16个二进制数组成一条指令或其它...
  • ARM汇编学习笔记一

    2021-02-04 03:11:09
     1.1ARM指令机器编码基本格式 格式 条件码 指令码 目的寄存器 操作数一寄存器 操作数二 所占位数 31-28 27-20 19-16 15-12 11-0  1.2ARM汇编语言指令格式   (opcoed){(cond)}{s} (Rd), (Rn){...
  • 什么是编译器

    2013-04-20 17:33:16
    机器语言是直接用二进制代码指令表达的计算机语言,指令是用0和1组成的一串代码,它们有一定的位数,并分成若干段,各段的编码表示不同的含义,例如某台计算机字长为16位,即有16个二进制数组成一条指令或其它信息...
  • 存储单元中的二进制代码(存储字)位数,存储字长可以是8位、16位、32位等。 早期计算机的存储字长一般和机器指令字长与数据字长相等,故访问一次主存便可取一条指令或一个数据。随着计算机的应用范围的不断扩大...
  • 机器的微指令格式中,共有8个控制字段,每个字段可分别激活5、8、3、16、1、7、25、4中控制信号。若采用字段直接编码方式设计微指令的操作控制字段,则其操作控制字段应该取__D_。 A.21 B.69 C.37 D.26 2单选(1...
  • 8位字长指令为寄存器(R-R)二地址类型,16位字长指令为寄存器-存储器(R-M)二地址变址寻址类型(-128变址范围)。 指令(字长) 使用频度f CPI I1(8位) 35% 1 I2(8位) 25% 2 I3(8位) 20% 2 I4(16位) ...
  • 汇编语言程序设计 第二版

    热门讨论 2012-08-12 14:23:02
     《汇编语言程序设计(第2版)》以16位/32位Intel CPU为介绍对象,以并行推进的方式介绍这两类CPU的指令系统,以达到相互参考、对照的效果。另外,本书还介绍了常用的编程环境和调试工具的使用方法。  在内容组织...
  • ARM 汇编中的立即数

    2010-08-11 15:01:00
    ARM 汇编中对汇编指令编码成 32bit 的机器码,其中对于立即数寻址的指令,其机器码构成如下: 31 28 | 27 26 25 | 24 21 | 20 | 19 16 | 15 12 | 11 8 | 7 0 | cond | 0 0 1 | opcode ...
  • 操作系统精髓与设计原理答案

    热门讨论 2011-11-19 15:15:08
    1.3、 一般而言,一条机器指令能指定的四种不同操作是什么? 答:这些动作分为四类:处理器-寄存器:数据可以从处理器传送到存储器,或者从存储器传送到处理器。处理器-I/O:通过处理器和I/O模块间的数据传送,...
  • 计算机组成原理测试题 如:一. 选择题(每选择1分,共20分) 1. 用ASCII码(七位)表示字符5和7是 (1) ;...设计一个16K×16位的芯片构成64K×16位的存储器,问: (1)需要几片芯片? (2) 画出组织结构图。
  • 27 2.3.3 定义变量 27 2.4 16 编程、32 编程,以及64 编程 28 2.4.1 通用寄存器 28 2.4.2 操作数大小 30 2.4.2 64 模式下的内存地址 30 2.4.4 内存寻址模式 31 2.4.5 内存寻址范围 34 2.4.6 使用的指令限制 ...
  • 27 2.3.3 定义变量 27 2.4 16 编程、32 编程,以及64 编程 28 2.4.1 通用寄存器 28 2.4.2 操作数大小 30 2.4.2 64 模式下的内存地址 30 2.4.4 内存寻址模式 31 2.4.5 内存寻址范围 34 2.4.6 使用的指令限制 ...
  • 27 2.3.3 定义变量 27 2.4 16 编程、32 编程,以及64 编程 28 2.4.1 通用寄存器 28 2.4.2 操作数大小 30 2.4.2 64 模式下的内存地址 30 2.4.4 内存寻址模式 31 2.4.5 内存寻址范围 34 2.4.6 使用的指令限制 ...
  • 27 2.3.3 定义变量 27 2.4 16 编程、32 编程,以及64 编程 28 2.4.1 通用寄存器 28 2.4.2 操作数大小 30 2.4.2 64 模式下的内存地址 30 2.4.4 内存寻址模式 31 2.4.5 内存寻址范围 34 2.4.6 使用的指令限制 ...
  • 具有处理多种数据类型的能力,可以对816位数,带符号数和不带符号数,压缩的和非压缩的BCD码十进制数进行处理;还提供了字符串操作指令;为支持构成多处理器系统,还专门提供了一组指令(WAIT、ESC)。 通过本章...

空空如也

空空如也

1 2 3 4
收藏数 72
精华内容 28
关键字:

机器指令16位编码