MOVS 和 MOV 的区别,还是有ADDS 和ADD在CPU中有一种特殊的寄存器, 在ARM中称为状态寄存器, 即CPSR寄存器, 该寄存器每一位都有专门的意义
movs会改变状态标记位, 意思就是发生相应的情况会改变状态寄存器对应的值
- 长度 32bit
- CPSR的低8位(包括I、F、T和M[4:0])称为控制位,程序无法修改,除非CPU运行于特权模式下,程序才能修改控制位!
- 8~27位是保留位,方便后期扩展
- N、Z、C、V均为条件码标志位。它们的内容可被算术或逻辑运算的结果所改变,并且可以决定某条指令是否被执行!
keil 生成反汇编和bin文件参考: https://www.cnblogs.com/zhugeanran/p/8493058.html
填写指令: - 生成汇编指令:
fromelf --text -a -c --output=all.dis Objects\StepMonitor.axf
其中 "all.dis" 和 "Objects\StepMonitor.axf" 都是相对于 ".uvprojx" 所在目录而言的 - 生成烧写bin文件
fromelf --bin --output=test.bin Objects\StepMonitor.axf
其中,烧写bin文件需要使用到 STM32CubeProgrammer
指令集arm 架构下的汇编指令集(stm32)
| EQU 给数字常量名取一个符号名,相当于C语言中的define |
| AREA 汇编一个新的代码段或者数据段 |
| SPACE 分配内存空间 |
| PRESERVE8 当前文件栈需按照 8 字节对齐 |
| EXPORT 声明一个标号具有全局属性,可被外部的文件使用 |
| DCD 以字为单位分配内存,要求 4 字节对齐,并要求初始化这些内存 |
| PROC 定义子程序,与 ENDP 成对使用,表示子程序结束 |
| IMPORT 声明标号来自外部文件,跟 C 语言中的 EXTERN 关键字类似 |
| B 跳转到一个标号 |
| END 到达文件末尾 ,文件结束 |
| IF,ELSE, ENDIF 汇编条件分支语句,跟 C 语言的 if else 类似 |
| MRS 加在特殊功能寄存器的值到通用寄存器 |
| MSR 存储通用寄存器的值到特殊功能寄存器 |
| CBZ 比较,比较结果为0就转移 |
| CBNZ 比较,比较结果非0就转移 |
| |
| ADR 从存储器中加载字到寄存器中 l 是 LDR[伪指令] 加载一个立即数或者一个地址值到一个寄存器。例如:ldr rd, = lable 如果 label 是立即数,那 Rd 等于立即数,如果 labe一个标识符,比如指针,那存到 Rd 的就是 label 这个标识符的地址 |
| LDM 多数据加载,从一片连续的空间加载多个字到若干寄存器 |
| LDR 加载字到寄存器 |
| LDRD 从连续的地址空间加载双字(64位整数)到两个寄存器 |
| LDRH 从存储器中加半字到一个寄存器中 |
| LDRB 从存储器中加载字节到寄存器中 |
| STR 把一个寄存器按字存储到存储器中 |
| STRH 把一个寄存器存的低【半】字存储到存储器中 |
| STRB 把一个寄存器的低字节存储到存储器中 |
| LDMIA 将多个字从存储器加载到 CPU 寄存器,先操作,指针在递增。 |
| SDM 存储若干寄存器中的字加载到一片连续的地址空间中 |
| STMDB 将多个字从 CPU 寄存器存储到存储器,指针先递减,再操作 |
| |
| ORR 按位或 |
| BX 直接跳转到由寄存器给定的地址 |
| BL 跳转到 标号对应的地址,并且把跳转前的下条指令地址保存到 LR |
| BLX 跳转到由寄存器 REG 给出的的地址,并根据 REG 的 LSB 切换处理器状 态 , 还 要 把 转 移 前 的 下 条 指 令 地 址 保 存 到 LR 。 ARM(LSB=0),Thumb(LSB=1)。CM3 只在 Thumb中运行,就必须保证 reg 的 LSB=1 否则一个fault 打过来 |
| |
| PC 程序寄存器,保留下一条CPU即将执行的指令 |
| LR 连接返回寄存器,保留函数返回后,下一条应执行的指令 |
| PUSH 压栈操作, eg: PUSH {r4-r7,lr}, 将r4-r7的值进行压栈操作 |
| MOVS 设置寄存器r0的值为0, eg: MOVS r0,#0 |
| SUB 减 SUB r0,r4,#0x10; r0 = r4 + 16; |
| ADD 加 同 SUM |
| SDIV 除 (SDIV r0,r4,r0) r0 = r4/r0 |
| CMP 比较指令 |
| ASRS 左移 eg:ASRS r4,r4,#16; r4 = r4 >> 16 |
| LSLS 右移位 |
| SXTB 带符号(Signed)扩展一个字节(Byte)到 32位 |
| SXTH 带符号(Signed)扩展一个半字(Half)到 32位 |
| UXTB 无符号(Unsigned)扩展一个字节(Byte)到 32位 |
| UXTH 无符号(Unsigned)扩展一个半字(Half)到 32位 |
| LSL 右移位操作 (ADD r0,r4,r4,LSL #1), 意思就是 r0 = r4*3 = r4+r4<<1; | x86 寄存器说明
| 8个通用寄存器:EAX、EBX、ECX、EDX、ESI、EDI、ESP、EBP |
| 1个标志寄存器:EFLAGS |
| 6个段寄存器:CS、DS、ES、FS、GS、SS |
| 5个控制寄存器:CR0、CR1、CR2、CR3、CR4 |
| 8个调试寄存器:DR0、DR1、DR2、DR3、DR4、DR5、DR6、DR7 |
| 4个系统地址寄存器:GDTR、IDTR、LDTR、TR |
| 其他寄存器:EIP、TSC等。 |
| |
| 32位: EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP |
| 16位: AX, BX, CX, DX, SI, DI, SP, BP |
| 8 位: AH, AL, BH, BL, CH, CL, DH, DL | 通用寄存器说明EAX:累加器(Accumulator), 它的低16位即是AX,而AX又可分为高8位AH和低8位AL。EAX是很多加法乘法的缺省寄存器,存放函数的返回值,用累加器进行的操作可能需要更少时间,在80386及其以上的微处理器中可以用来存放存储单元的偏移地址。AX寄存器是算术运算的主要寄存器。
EBX:基地址寄存器(Base Register), 它的低16位即是BX,而BX又可分为高8位BH和低8位BL。主要用于在内存寻址时存放基地址。 ECX:计数寄存器(Count Register),它的低16位即是CX,而CX又可分为高8位CH和低8位CL。在循环和字符串操作时,要用它来控制循环次数;在位操作 中,当移多位时,要用CL来指明移位的位数;是重复(REP)前缀指令和LOOP指令的内定计数器。 EDX:数据寄存器(Data Register),它的低16位即是DX,而DX又可分为高8位DH和低8位DL。在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址;且总是被用来放整数除法产生的余数。 ESI/EDI:分别叫做源/目标索引寄存器(Source/Destination Index Register),它们的低16位分别是SI、DI。它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目标串。此外,它们又作为通用寄存器可以进行任意的常规的操作,如加减移位或普通的内存间接寻址。 EBP/BSP:分别是基址针寄存器(Base Pointer Register)/堆栈指针寄存器(Stack Pointer Register),低16位是BP、SP,其内存分别放着一个指针,该指针***指向系统栈最上面一个栈帧的栈顶/底部。主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。并且规定:BP为基指针(Base Pointer)寄存器,用它可直接存取堆栈中的数据;SP为堆栈指针(Stack Pointer)寄存器,用它只可访问栈顶。在32位平台上,ESP每次减少4字节。EBP最经常被用作高级语言函数调用的"框架指针"(frame pointer),EBP 构成了函数的一个框架,在C++反汇编中EBP通常是局部变量、传进来的参数。这里要注意在intel系统中栈是向下生长的(栈越扩大其值越小,堆恰好相反)。在通常情况下ESP是可变的,随着栈的生长而逐渐变小,而ESB寄存器是固定的,只有当函数的调用后,发生入栈操作而改变,在函数执行结束之后需要还原。 x86 汇编指令,这里只整理常用的, 方便后期查询%rax 一般用作累加器(Accumulator)
%rbx 一般用作基址寄存器( Base )
%rxc 一般用来计数( Count )
%rdx 一般用来存放数据( Data )
%rsi一般用作源变址( Source Index )
%rdi 一般用作目标变址( DestinatinIndex )
%rbp 一般用作基址指针( Base Pointer )
%rsp 一般用作堆栈指针( Stack Pointer )
| 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) |
| IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} ) |
| OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器 ) |
| 输入输出端口由立即方式指定时,其范围是 0-255; |
| 由寄存器 DX 指定时,其范围是 0-65535. |
| 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. |
| LAHF 标志寄存器传送,把标志装入AH. |
| SAHF 标志寄存器传送,把AH内容装入标志寄存器. |
| PUSHF 标志入栈. |
| POPF 标志出栈. |
| PUSHD 32位标志入栈. |
| POPD 32位标志出栈. |
| ADD 加法. |
| ADC 带进位加法. |
| INC 加 1. |
| AAA 加法的ASCII码调整. |
| DAA 加法的十进制调整. |
| SUB 减法. |
| SBB 带借位减法. |
| DEC 减 1. |
| NEG 求反(以 0 减之). |
| CMP 比较.(两操作数作减法,仅修改标志位,不回送结果). |
| AAS 减法的ASCII码调整. |
| DAS 减法的十进制调整. |
| MUL 无符号乘法.结果回送AH和AL(字节运算),或DX和AX(字运算), |
| IMUL 整数乘法.结果回送AH和AL(字节运算),或DX和AX(字运算), |
| AAM 乘法的ASCII码调整. |
| DIV 无符号除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算). |
| IDIV 整数除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算). |
| AAD 除法的ASCII码调整. |
| CBW 字节转换为字. (把AL中字节的符号扩展到AH中去) |
| CWD 字转换为双字. (把AX中的字的符号扩展到DX中去) |
| CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去) |
| CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去) |
| |
| DS:SI 源串段寄存器 :源串变址. |
| ES:DI 目标串段寄存器:目标串变址. |
| CX 重复次数计数器. |
| AL/AX 扫描值. |
| D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量. |
| Z标志 用来控制扫描或比较操作的结束. |
| 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 |
| LOOP CX不为零时循环. |
| LOOPE/LOOPZ CX不为零且标志Z=1时循环. |
| LOOPNE/LOOPNZ CX不为零且标志Z=0时循环. |
| JCXZ CX为零时转移. |
| JECXZ ECX为零时转移. |
| DW 定义字(2字节). |
| PROC 定义过程. |
| ENDP 过程结束. |
| SEGMENT 定义段. |
| ASSUME 建立段寄存器寻址. |
| ENDS 段结束. |
| END 程序结束. |
| CLC 进位位置0指令 |
| CMC 进位位求反指令 |
| STC 进位位置为1指令 |
| CLD 方向标志置1指令 |
| STD 方向标志位置1指令 |
| CLI 中断标志置0指令 |
| STI 中断标志置1指令 |
| NOP 无操作 |
| HLT 停机 |
| WAIT 等待 |
| ESC 换码 |
| LOCK 封锁 |
| JE 指令跳转 | x86 如何生成汇编- gcc -S,生成文件为 .s 后缀名
- objdump -d [编译的二进制文件,如a.out], 反汇编,二进制文件和汇编是可以相互转化的
|