汇编指令(代码片段)

y4247464 y4247464     2023-04-20     196

关键词:

汇编指令:逻辑指令、算术指令、跳转指令

.text
    
    /* 逻辑指令 */
    mov r7,#0x88
    @ and r0,r1,#0xFF     //r0=r1&0xFF
    @ orr r7,r7,#0xffff77 //r7=r7&0x88,清除7号3号位,但立即数太大,报错
      bic r7,r7,#0x88       //清除r7中7号3号
    @ tst r0,#0x20        //测试5号位是否为0,为0则Z(30号位)标志置1
    @ cmp r1,r0           //将R1与R0相减做比较,并根据结果设置CPSR的标志位
    
    @ eg: 使能中断和快速中断
    @       mrs r0,cpsr     //对cpsr操作需要以寄存器为中介
    @       bic r0,r0,#0xc0 //I-6,F-7,使能,将6?7位清零
    @       msr cpsr,r0
        
    @ eg: 判断当前工作状态位ARM状态,是则切换到user工作模式?
    @     mrs r0,cpsr
    @     tst r0,#0x20    //5号位-1-Thumb状态,0-ARM状态
    @     andeq r0,#0xffffffe0  //1110 0000 ,先把M[4:0]清零
    @     orreq r0,#0x10  //将4号位置1
    @     mrseq cpsr,r0   //上一判断为真,则执行
    
    /* 算术指令 */
    @     add r0,r1,r2    //ro=r1+r2
    @      sub r0,r1,#3    //ro=r1-3
    @     sub r0,r1,r2,LSL#1      //r0=r1-(r2<<1)
    @      mul r1,r2,r3    //r1=r2*r3
    
    /* 跳转指令 */
    @      b       main    //跳转到标号为main的代码处
    @      bl   func    //保存下一条要执行的指令的位置到LR寄存器,跳转函数func
    @                   //跳转代码结束后,使用MOV PC,LR指令跳回来
    @      beq  addr    //当CPSR寄存器中的Z条件码置位时,跳转到该地址处
    @      bne  addr    //当不等时,跳转到地址addr
        
    .end

 

用汇编实现以下功能:

 1 void main(void)
 2 
 3      int ret=0;
 4      func1(2);
 5      while(1)  
 6 
 7  
 8 func1(int a)
 9 
10      if(a=2)
11         return func2(a); 
12      else
13         return func3(a);     
14 
15 
16 func2(int a)
17 
18      return a+3;
19 
20 
21 func3(int a)
22 
23      return a-1;
24 

 

示例代码(1)

 1 .text
 2     
 3 main:
 4     mov r5,#0  //0x00
 5     mov r0,#2  //0x04
 6     bl func1   //PC:0x08 LR:0x0C(12)
 7 
 8 main_end:
 9     b    main_end  @ while(1) ; 死循环
10     
11 func1:
12     cmp r0,#2   //PC:0x10(16) LR:0x0C
13     bleq func2  //PC:0x14(20) LR:0x18(24) 注意此处LR被跳转指令里面嵌套的跳转指令覆盖了,导致无法跳回第一次跳转指令的下一指令
14     blne func3  //跳转回来时,PC:0x18  LR:0x18 往下走到0x1C,
15 func1_end:
16     mov pc,lr   //PC:0x1C(28) LR:0x18,又将跳回0x18,成死循环,跳不出func1
17     
18 func2:
19     add r0,#3   //PC:0x20(32) LR:0x18
20     mov pc,lr   //PC:0x24     LR:0x18
21     
22 func3:
23     sub r0,r0,#1 @或者写成sub r0,#1
24 func2_end:
25     
26     .end
27     

为了避免跳转指令嵌套导致LR被覆盖的问题,可以在嵌套调用的函数里另设寄存器R储存会被覆盖的LR值,在跳转时,将R赋PC就可以

 1 .text
 2     
 3 main:
 4     mov r5,#0  //0x00
 5     mov r0,#2  //0x04
 6     bl func1   //PC:0x08 LR:0x0C(12)
 7 
 8 main_end:
 9     b    main_end  @ while(1) ; 死循环
10     
11 func1:
12     mov r12,lr    //保存LR:0x0C,避免被覆盖
13         cmp r0,#2   
14     bleq func2  // 注意此处LR被跳转指令里面嵌套的跳转指令覆盖了,导致无法跳回第一次跳转指令的下一指令
15     blne func3  
16 func1_end:
17     mov pc,r12   
18     
19 func2:
20     add r0,#3   
21     mov pc,lr   
22     
23 func3:
24     sub r0,r0,#1 @或者写成sub r0,#1
25 func2_end:
26     
27     .end
28     

 

 1 .text
 2     
 3     //load/store架构规定,存储器之间不能直接拷贝,需要通过寄存器做中转
 4     ldr r0,[r1]    //r0=*r1,r1里面存放的是地址,把该地址存放的内容读入到r0
 5                    //LDRB(byte)  LDRH(half word)
 6     ldr r0,[r1,#8] //r0= *(r1+8) 存储器地址为r1+8的字数据读入寄存器0
 7     ldr pc,_irq    //pc= *(_irq) 将标号中的内容放入PC中
 8     
 9     str r0,[r1]    // *r1=r0   将r0中的值写入存储器地址为r1的空间中,并将r1+4写入r1
10     
11     str r0,[r1],#4 //r0=*r1,r1=r1+4 ,将r0中的值写入存储器地址为r1的空间中,并将r1+4写入r1
12     
13     str r0,[r1,#4] //*r0=(r1+4) 将r0中的字数据写入以r1+4为地址的内存中
14     
15     .end

技术图片

 

 

示例:拷贝srcBuf里的内容到destBuf中

.text
    
    ldr  r0,=srcBuf   @r0存放src的地址
    ldrb r1,[r0]      @将r0里地址(src)里的(1byte)数据存入r1
    ldr  r0,=destBuf  @r0存放dest地址
    strb r1,[r0]      @将r1里的数据存入r0里的地址的空间
    
scrBuf:
    .byte 0x01,0x02,0x03,0x04

.data destBuf: .space
8 .end

 

示例2:用汇编实现以下功能:

main()

    int i=0;
    const char buf[]=1,2,3;
    char destbuf[8];
    for(i=0;i<3;i++)
    
         destbuf[i] = buf[i];  
       

main:
    mov  r5,#0       @用于for循环计数
    ldr  r7,=buf
    ldr  r8,=destbuf
    
loop:
    cmp  r5,#3
    beq  main_end
    add  r5,#1
    
    ldrb r0,[r7],#1  @将r7里的地址buf里的1byte数据存入r0后,r7=r7+1
    strb r0,[r8],#1  @将r0的值赋给r8里的地址dest空间后,r8=r8+1
    b loop
    
main_end:
    b main_end

buf:
    .byte 1,2,3   @定义在代码段仅可读,在数据段可读可写

    .data 
    
destbuf:
    .space 8    @定义空间大小为8个字节
    
    .end

技术图片

 

 

GNU汇编伪指令

.text                  // 将定义符开始的代码编译到代码段

.data                  // 将定义符开始的代码编译到数据段

.end                   //文件结束

.equ   GPG3, 0xFFFF    //定义宏

.byte                  //定义变量1字节

.word                  //定义word变量(4字节 32位机)

.string                //定义字符串  .string  "abc"

.global   _start       //声明_start为去全局符号

 

批量操作指令

ia --- Increment After  

ib --- Increment Before

da --- Decrement After

db --- Decrement Befor

stmdb和ldmia指令一般配对使用,stmdb用于将寄存器压栈,ldmia用于将寄存器弹出栈,作用是保存使用到的寄存器。

详见:https://blog.csdn.net/minsophia/article/details/53080183

技术图片

 

 

技术图片

 

汇编指令初步(代码片段)

汇编指令初步指令和数据的存储方式数据在SRAM存储器中的存储方法AVRiATtiny88处理器从SRAM起始地址0x100开始存储数据,0x100之前的空间预留给系统使用存储空间|功能|先后顺序-|-|-data区|存储已初始化的变量|先bss区|存储未初始化的... 查看详情

汇编程序基本指令集(代码片段)

...形式的序列(包含字符串形式的操作码以及操作数助记符)汇编语言基本指令集总说明(所有的指令都要遵守的)对于双操作数指令(如:MOV,A 查看详情

汇编学习--第三天(代码片段)

4.1一个源程序从写出到执行的过程汇编语言源程序包含两种指令:1.汇编指令2.伪指令汇编指令会被编译为机器指令,被CPU执行伪指令不会,会被编译器执行 assumecs:codesgcodesgsegmentmovax,0123hmovbx,0456haddax,bxaddax,axmovax,4c00hint21hcodesg... 查看详情

arm汇编(代码片段)

汇编指令和伪指令的区别汇编指令是cpu机器指令的助记符,代表这个cpu的功能。伪指令本质不是指令,只是和汇编指令写在同一个代码中,它由编译器提供,用于指导编译过程,经过编译后伪指令最终不会生... 查看详情

汇编语言指令是机器指令的符号化(代码片段)

汇编语言指令是机器指令的符号化,与机器指令存在着直接的对应关系,所以汇编语言同样存在着难学难用、容易出错、维护困难等缺点。但是汇编语言也有自己的优点:可直接访问系统接口,汇编程序翻译成的机器语言程序的... 查看详情

汇编语言实验1用机器指令和汇编指令编程(代码片段)

四、实验结论1. 教材实验1(P45)(1)使用Debug,将下面的程序段写入内存,逐条执行,观察每条指令执行后CPU中相关寄存器的内容变化使用e命令修改内存:使用a命令修改内存:(2)将下面3条指令写入从2000:0开始的内存单... 查看详情

汇编多条件转移指令(代码片段)

CMP指令 无符号数比较转移指令(A:大B:小E:等于)note:1)cmp指令后用以上跳转比较大小      2)记忆指令和意义    带符号数比较转移指令(G:大 L:小 E:等于) note:1)cmp指... 查看详情

mips汇编指令集(代码片段)

MIPS汇编MIPS指令集MIPS指令集属于精简指令集MIPS的所有指令都是32位,指令格式简单,而X86的指令长度不是固定的。简单的指令和格式易于译码和流水线操作,但是代码密度不高,导致二进制文件大MIPS有32个通用寄... 查看详情

arm汇编简单介绍(代码片段)

1.汇编文件说明:  汇编文件以【.s】结尾的文件格式  注释:多行注释/**/  ;单行注释@ 2. 符号说明:  1)汇编指令,一条指令对应一个机器码,完成一定的功能  2)伪指令,一条指令对应多条机器码,... 查看详情

汇编中的指令对齐(代码片段)

title:汇编中的指令对齐tags:ARMdate:2018-10-2320:50:39---汇编中的指令对齐搜索下官方文档的索引.align,有如下描述,也就是有两种情况,对于ARM,表示的是末尾几个0,也就是2^x了.具体填充格式可以指定alignabs-expr,abs-expr,abs-expr,参考... 查看详情

8080汇编指令(代码片段)

数据传送指令(1)mova,bb的数据传送到a处,注意不能内存到内存中(会引起机器码过长,指令周期过长)关于周期一些术语(2)xchga,bxchg是exchange,也叫交换指令,效率高于mov会使用暂存器... 查看详情

8080汇编指令(代码片段)

数据传送指令(1)mova,bb的数据传送到a处,注意不能内存到内存中(会引起机器码过长,指令周期过长)关于周期一些术语(2)xchga,bxchg是exchange,也叫交换指令,效率高于mov会使用暂存器... 查看详情

汇编一(代码片段)

前言汇编语言的概念汇编语言的组成其他相关的概念存储器存储单元数据和指令汇编的简单指令段的概念内存单元地址段寄存器汇编语言的概念 汇编语言(AssemblyLanguage)是任何一种用于电子计算机、微处理器、微控制... 查看详情

实验2用机器指令和汇编指令编程(代码片段)

(注:本文默认数字为16进制数)实验2.1首先:使用e命令修改0021:0~0021:f数据,及修改后查看是否正确写入。  输入代码前的预判:movax,0021movds,axmovax,2200movss,axmovss,axmovsp,0100movax,[0];ax=3130;addax,[2];ax=3130+3332=6462;movbx,[4];bx=3534;addbx,[... 查看详情

从汇编指令角度理解函数调用过程(代码片段)

从指令角度理解函数调用过程示例代码生成指令具体过程参考资料示例代码我们首先来看如下代码:intsum(inta,intb) inttemp=0; temp=a+b; returntemp;intmain() inta=10; intb=20; intret=sum(a,b); return0;生成指令intsum(inta,intb)/ 查看详情

汇编语言str指令(代码片段)

汇编str指令,将值写到某个地址。 示例:/*汇编点亮一个LED灯*/.text.global_startldrr1,=0x56000050ldrr0,=0x100/*相当于movr0,#0x100*/strr0,[r1]ldrr1,=0x56000054ldrr0,=0/*movr0,#0*/strr0,[r1]bhalt  strr0,[r1]将r0的值写到r1地址里 &n 查看详情

arm汇编基础详解(代码片段)

目录前言1.GNU汇编语法2.Cortex-A7常用汇编指令2.1处理器内部数据传输指令2.2存储器访问指令2.3压栈和出栈指令(了解)2.4跳转指令2.5算术运算指令2.6逻辑运算指令前言我们在进行嵌入式Linux开发的时候是绝对要掌握基本的AR... 查看详情

汇编加减乘除指令(代码片段)

一、ADDADCINC和SUBSBBDEC    1.加法指令     2.减法指令 CF(进位计数器,存进位值)sub和add指令要求:DST、SRC 不能同时为存储器,DST不能为立即数,运算结果对标志位有影响。sbb和adc指令要求... 查看详情