怎么将mov,mvn,add,orr,cmp,swp写在一个汇编程序中并实现相应功能

时间:2018.10.29 发布人:U3092473758

怎么将mov,mvn,add,orr,cmp,swp写在一个汇编程序中并实现相应功能

已解决问题

谷歌U3092473758用户在2018.10.29提交了关于“王者荣耀怎么将mov,mvn,add,orr,cmp,swp写在一个汇编程序中并实现相应功能”的提问,欢迎大家涌跃发表自己的观点。目前共有2个回答,最后更新于2024-08-06T02:21:19。

要求写在一个程序中,并实现各自功能。用keil写

希望大家能够帮助她。

详细问题描述及疑问:

要求写在一个程序中,并实现各自功能。用keil写

期待您的答案,滴水之恩,来日我当涌泉相报 !
希望以下的回答,能够帮助你。

第1个回答

用户名:贝尔梅来自尔娜美  

件剧单陆ARM汇编程序特点:l所有运算处理都是发生通用寄存器(一般是R0~R14)的之中.所有存储器空间(如C语言变量的本质就是一个存储器空间上的几个BYTE).的值的处理,都是要传送到通用寄存器来完成.因此代码中大量看到LDR,STR指令来传送值.l问答ARM汇编语句中.当前语句很多时候要隐含的使用上一句的执行结果.而且上一句的执行结果,是放在CPSR寄存器里,(比如说造秋起胜离父了急晚水进位,为0,为负…)CMPR0,R1BNENoMatch比如上一句,BNE隐含的使用的上一句CMP执行结果.NE后缀表示使用Z标志位.两句合起来的意思就起医更义照病光阳除神制是,如果R0,R1的值不相等,就跳转到NoMatch处执行.之地总终光配做计反注意,PC=R15,但为阿相该轻贵CPSR=R16,AR虽笔期可境两胞验M伪指令不是必须的,但是一个完整没有伪指令几乎很难写出来.n比如一个程序至少包含READONLYAREA和ENTRY,否则CPU都无法知道从哪里开始运行lARM商推安局号请国的属于RISC,指令并不多,但是可以带后缀表示扩展出不同用法,这里与X86汇编完全不交诗移套同风格n如BNE实际上是B设策今神外七地销给伟土指令的变种,本质还同一早志曲配空校害攻紧类指令.只是多一个对CPSR的Z标志位的判断。ARM常用指令,伪指令ARM常用指令并不太多,因此使用阅读ARM汇编代码,并不太困难.以下是使用频维负三弱球破区老求底红率最高的指令和伪指令,并不是完整的指令集的教干容身材。详细指令参见参考**。lB并,BLlMOV,MV次假团谁助己NlLDR,STRlADD,SUB,ADC,SBC,MULlAND,ORR,XOR,TST,BIClCMPlLDM/STMlnop1.跳转语句B,BL程序流程的跳转,在ARM程序中有两种方法可以实现程序流程的跳转指令用于实现l使用专门的跳转指令Bl直接向程序计数器PC写入跳转地址值n这是几乎是任何补员旧食知怎富处一种CPU必备的机器,PC表示CPU当前执行语句位置,改变PC的值,相当于实从来径听儿做故现程序跳转n如实现类似C语言的Return语句,就是用MOVPC,LR基肉n这里可以在任意4G的空间进行跳转B指令(Branch)表示无条件跳转.Bmain;跳转到标号为main地代码处BL指令(BranchwithLink)表示带返回值的跳转.BL比B多做一步,在跳转前,BL会把当前位置保存在R14(即LR寄存器),当跳转代码结束后,用MOVPC,LR指令跳回来,这实际上就是C语言执行函数的用法,汇编里调子程序都用BL,执行完子函数后,可以用MOVPC,LR跳回来.BLdelay;执行子函数或代码段delay,delay可以为C函数.与MOVPC,XXX能在4G空间跳转不同,B语句只能32M空间跳转,(因为偏移量是一个有符号26bit的数值=32M)2.传输**指令MOV,MVNnMOV(MOVE)指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器MOVR0,R1;把R1的值传到R0MOVR3,#3;把常数3传给R3,MOV中用#表示常数,这个值不能超过nMVN(MOVENegative)取反后再传值,比MOV多了一步取反MVNR0,#0;把0取反(即-1)传给R0MVNR1,R2;把R2的值取反传给R13.加载/存储指令,LDR,STRnLDR,STR是用于寄存器和外部存储器交换**指令,注意与MOV的区别,后面只在寄存器或常数交换.uLDR/STR可以采用多种寻址方式,以下只举出使用频率最高几种用法nLDR(load)用于把一个32Bit的WORD**从外部存储空间装入到寄存器中LDRR0,[R1];R1的值当成地址,再从这个地址装入**到R0(R0=*R1)LDRR1,=0x30008000;把地址0x30008000的值装入到R1中,LDR中用常数要用=打头.(注意跟MOV的区别,MOV是#)ldrr0,=(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)用位与的方法赋值nSTR(Store)用于把一个寄存器的值存入外部存储空间,是LDR的逆操作.STRR0,[R1];把R0的值,存入到R1对应地址空间上(*R1=R0)STRR0,=0x30008000;把R0中值存入到地址0x30008000S2C2440的中CPU内核以外的模块的控制寄存器空间也是属于外部空间,所以也得用如下指令LDRR0,=GPFDAT4.算术运算指令,ADD/ADC,SUB/SBC,MULnADD加法指令ADDR0,R1,R2;R0=R1+R2ADDR0,R1,#3;R0=R1+3nADC带进位加法指令,即除了加两个数以外,还要把CPSR的C值也要带进来u通常用于大数(超过32Bit整数)相加,这时单用ADD不能处理,必须折成两步,其中一步用ADC.u以下是做64Bit的加法ADDSR0,R1,R2;R0=R1+R2,ADDS中S表示把进位结果写入CPSRADCR5,R3,R4;R5=R3+R4+CnSUB减法指令SUBR0,R1,R2;R0=R1-R2SUBR0,R1,#3;R0=R1-3nSBC带进位减法指令,即除了加两个数以外,还要把CPSR的C值也要带进来,类似ADCu以下是做64Bit的减法SUBSR0,R1,R2;R0=R1-R2,SUBS中S表示把进位结果写入CPSRSBCR5,R3,R4;R5=R3-R4-CnMUL乘法指令MULR0,R1,R2;R0=R1*R2MULR0,R1,#3;R0=R1*35.位操作指令AND,ORR,TST,BICnAND位与指令ANDR0,R1,R2;R0=R1&R2ANDR0,R1,#0xFF;R0=R1&0xFFnORR位或指令ORRR0,R1,R2;R0=R1|R2ORRR0,R1,#0xFF;R0=R1|0xFFnTST测试某一位是否为1,并把结果写入CPSR,供下一句使用TSTR1,#0xffe;等同于if(R1&0xffe)TSTR1,#%1;测试最低位是否为1,%表示二进制nBIC清位操作BICR0,R0,#0xF;等同于R0&=~(0xF)BICR0,R0,#%1011;该指令**R0中的位013,其余的位保持;%表示是二进制,0x表示十六进制6.比较指令CMPnCMP比较两个操作数,并把结果存入CPSR供下一句语句使用CMPR0,R1;比较R0,R17.多寄存器语句传输指令,LDM,STM类似于一次传一个BUFFER到寄存器当中,或反过来.后面一般要接一个地址改变方法nLDM从BUFFER传**多个寄存器传输**到LDMIAR0!,{R3-R9};加R0指向的地址上连续空间的**,保存到R3-R9当中,!表示R0值更新,IA后缀表示按WORD递增LDMFDSP!,{R0-R7,PC}^;恢复现场,异常处理返回,^表示不允许在用户模式下使用。nSTM从寄存器列表向存储空间传值。STMIAR1!,{R3-R9};将R3-R9的**存储到R1指向的地址上,R1值更新。STMFDSP!,{R0-R7,LR};现场保存,将R0~R7,LR入栈stmfdsp!,{r8-r9},把SP寄存器对庆的地址的值存到R8,R9当中.!表示最后的值写入SP中。Fd表示8.ARM指令的变形大部分指令后位可以接与S两个特殊位来表示,对CPSR特殊的一些判断S,表示当前指令执行后把结果改写CPSRsubs,Adds取决于具体条件,只有CPSR满足指定条件时才指这一指令BEQ实际上B+EQ的条件执行.addne表示ADD+NE才开始加.9.ARM指令的寻址方式寻址方式是根据指令中给出的地址码来**真实的地址,ARM中有9种寻址方法l寄存器寻址直接用寄存器编号来寻址,最为常用MOVR1,R2;R2->R1l立即数寻址即指令中的地址码是操作数本身,可以立即取出使用,立即数前带一个#表示,否则表示一个地址SUBSR0,R0,#1;R0-1->R0注意与SUBSR0,R0,1区别l寄存器偏移寻址这是ARM特有的寻址模式,当第2操作数是寄存器,在执行操作之前,可以做一次移位操作MOVR0,R2,LSL#3;R2的逻辑左移3位,结果放入R0,即R0=R2*8ANDSR1,R1,R2,LSLR3;RS的值左移R3位,然后和R1相与操作,结果放入R1移位操作有LSL(逻辑左移),LSR(逻辑右移),ASR(算术右移),ROR(循环右移)RRX带扩展的循环右移l寄存器间接寻址即寄存器中值是一个地址,用[]来取出**到地址当中LDRR2,[R0];把R0的值当成地址,取出相应值,赋给R2l基址寻址把寄存器的地址值加上一个偏移量LDRR2,[R3,#0x0F];R3中的值加上0x0F,从这个地址取出值赋给R@l相对寻址基址寻址的变形,由PC寄存器提供基准地址,指令中地址段作为偏移量.两者相加即是有效地址,以下是BL采用相对寻址BLNEXT…NEXT…MOVPC,LR;从子程序返回10.ADSARM的伪指令类似于C语言的宏,由汇编程序预处理.l符号定义指令全局变量定义GBLA,GBLL,GBLS局域变量定义LCLA,LCLL,LCLS变量赋值**TA,**TL,**TS其中上述伪指令中,最后面的A表示给一个算术变量赋值,L表示用于给一个逻辑变量赋值,s表示给一个字符串赋值GBLLcodedbg;声明一个全局的逻辑变量Codebg**TL{TRUE};设置变量为{TRUE}LCLAbitno;声明一个算术变量Bitno**TA8;设变量值为8l**定义伪指令nSPACE定义一个内存空间,并用0初始化{label}SPACEexprDataBufSPACE100;定义100字节长空间,unsignedcharDataBuf[100];nDCB定义一个连续字节内存空间,用伪指令的表达式expr来初始化.一般可以用定义**表格,或文字字符串.(这时等同于**TS),用于初始二进制BUFFER{label}DCBexpr{,expr…}DestDCB-120,20,36,55;等同于unsignedcharDest[]={-120,20,36,55};nDCU定义的一段字的内存空间(DCB是字节),并用后面表达式初始化_RE**TDCUReset;等同于DWORD_RE**T[]={Reset};nMAP定一个结构化内存,相当于定义一个C结构nFILED定义一个结构化内存的成员MAP0x00,R9;定义内存表,地址为R9TimerFIELD4;定义**域Timer,长为4字AttribFIELD4;定义**域Attrib,长为4字StringFILED100;定义**域String,长为100字相当于C语言的定义:struct{DWORDTimer;DWORDAttrib;CharString[100];}R9;11.杂项的伪指令n字节对齐ALIGNALIGN;声明4字节对齐n定义一个数字常量定义EQUNAMEEQUexpr{type}PLLCONEQU0xE01FC080;定义PLLCON,类似于C的宏或C++的常量n包含文件GET和INCLUDEINCLUDElpc2106.incnNOP空指令在汇编时会被ARM的空操作代替,比如MOVR0,R0,一般用于延时与占位。n声明一个外部符符号IMPORT,EXTERNIMPORT,EXTERN向外部导入一个符号,一般是外部程序全局变量n条件编译:[]。类似于C的#ifdef之类定义。格式:[条件表达式满足条件分支|不满足条件分支]示例1:[ENTRY_BUS_WIDTh**=32;类似#ifENTRY_BUS_WIDTh**=32bChangeBigEndian;DCD0xea000007];类似#endif示例2:[CLKDIV_VAL>1;类似#ifCLKDIV_VAL>1blMMU_SetAsyncBusMode|;类似#elseblMMU_SetFastBusMode;defaultvalue.];类似#endif示例3[Th**UMBCODE类似#ifdefTh**UMBCODEbxlr|;类似#elsemovpc,lr];类似#endifn段定义AREAn指令集定义CODE16和CODE32

第2个回答

用户名:娜美小宅女  

ARM汇编程序特点:l所有运算处理都是发生通用寄存器(一般是R0~R14)的之中.所有存储器空间(如C语言变量的本质就是一个存储器空间上的几个BYTE).的值的处理,都是要传送到通用寄存器来完成.因此代码中大量看到LDR,STR指令来传送值.lARM汇编语句中.当前语句很多时候要隐含的使用上一句的执行结果.而且上一句的执行结果,是放在CPSR寄存器里,(比如说进位,为0,为负…)CMPR0,R1BNENoMatch比如上一句,BNE隐含的使用的上一句CMP执行结果.NE后缀表示使用Z标志位.两句合起来的意思就是,如果R0,R1的值不相等,就跳转到NoMatch处执行.注意,PC=R15,CPSR=R16,ARM伪指令不是必须的,但是一个完整没有伪指令几乎很难写出来.n比如一个程序至少包含READONLYAREA和ENTRY,否则CPU都无法知道从哪里开始运行lARM的属于RISC,指令并不多,但是可以带后缀表示扩展出不同用法,这里与X86汇编完全不同风格n如BNE实际上是B指令的变种,本质还同一类指令.只是多一个对CPSR的Z标志位的判断。ARM常用指令,伪指令ARM常用指令并不太多,因此使用阅读ARM汇编代码,并不太困难.以下是使用频率最高的指令和伪指令,并不是完整的指令集的教材。详细指令参见参考**。lB,BLlMOV,MVNlLDR,STRlADD,SUB,ADC,SBC,MULlAND,ORR,XOR,TST,BIClCMPlLDM/STMlnop1.跳转语句B,BL程序流程的跳转,在ARM程序中有两种方法可以实现程序流程的跳转指令用于实现l使用专门的跳转指令Bl直接向程序计数器PC写入跳转地址值n这是几乎是任何一种CPU必备的机器,PC表示CPU当前执行语句位置,改变PC的值,相当于实现程序跳转n如实现类似C语言的Return语句,就是用MOVPC,LRn这里可以在任意4G的空间进行跳转B指令(Branch)表示无条件跳转.Bmain;跳转到标号为main地代码处BL指令(BranchwithLink)表示带返回值的跳转.BL比B多做一步,在跳转前,BL会把当前位置保存在R14(即LR寄存器),当跳转代码结束后,用MOVPC,LR指令跳回来,这实际上就是C语言执行函数的用法,汇编里调子程序都用BL,执行完子函数后,可以用MOVPC,LR跳回来.BLdelay;执行子函数或代码段delay,delay可以为C函数.与MOVPC,XXX能在4G空间跳转不同,B语句只能32M空间跳转,(因为偏移量是一个有符号26bit的数值=32M)2.传输**指令MOV,MVNnMOV(MOVE)指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器MOVR0,R1;把R1的值传到R0MOVR3,#3;把常数3传给R3,MOV中用#表示常数,这个值不能超过nMVN(MOVENegative)取反后再传值,比MOV多了一步取反MVNR0,#0;把0取反(即-1)传给R0MVNR1,R2;把R2的值取反传给R13.加载/存储指令,LDR,STRnLDR,STR是用于寄存器和外部存储器交换**指令,注意与MOV的区别,后面只在寄存器或常数交换.uLDR/STR可以采用多种寻址方式,以下只举出使用频率最高几种用法nLDR(load)用于把一个32Bit的WORD**从外部存储空间装入到寄存器中LDRR0,[R1];R1的值当成地址,再从这个地址装入**到R0(R0=*R1)LDRR1,=0x30008000;把地址0x30008000的值装入到R1中,LDR中用常数要用=打头.(注意跟MOV的区别,MOV是#)ldrr0,=(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)用位与的方法赋值nSTR(Store)用于把一个寄存器的值存入外部存储空间,是LDR的逆操作.STRR0,[R1];把R0的值,存入到R1对应地址空间上(*R1=R0)STRR0,=0x30008000;把R0中值存入到地址0x30008000S2C2440的中CPU内核以外的模块的控制寄存器空间也是属于外部空间,所以也得用如下指令LDRR0,=GPFDAT4.算术运算指令,ADD/ADC,SUB/SBC,MULnADD加法指令ADDR0,R1,R2;R0=R1+R2ADDR0,R1,#3;R0=R1+3nADC带进位加法指令,即除了加两个数以外,还要把CPSR的C值也要带进来u通常用于大数(超过32Bit整数)相加,这时单用ADD不能处理,必须折成两步,其中一步用ADC.u以下是做64Bit的加法ADDSR0,R1,R2;R0=R1+R2,ADDS中S表示把进位结果写入CPSRADCR5,R3,R4;R5=R3+R4+CnSUB减法指令SUBR0,R1,R2;R0=R1-R2SUBR0,R1,#3;R0=R1-3nSBC带进位减法指令,即除了加两个数以外,还要把CPSR的C值也要带进来,类似ADCu以下是做64Bit的减法SUBSR0,R1,R2;R0=R1-R2,SUBS中S表示把进位结果写入CPSRSBCR5,R3,R4;R5=R3-R4-CnMUL乘法指令MULR0,R1,R2;R0=R1*R2MULR0,R1,#3;R0=R1*35.位操作指令AND,ORR,TST,BICnAND位与指令ANDR0,R1,R2;R0=R1&R2ANDR0,R1,#0xFF;R0=R1&0xFFnORR位或指令ORRR0,R1,R2;R0=R1|R2ORRR0,R1,#0xFF;R0=R1|0xFFnTST测试某一位是否为1,并把结果写入CPSR,供下一句使用TSTR1,#0xffe;等同于if(R1&0xffe)TSTR1,#%1;测试最低位是否为1,%表示二进制nBIC清位操作BICR0,R0,#0xF;等同于R0&=~(0xF)BICR0,R0,#%1011;该指令**R0中的位013,其余的位保持;%表示是二进制,0x表示十六进制6.比较指令CMPnCMP比较两个操作数,并把结果存入CPSR供下一句语句使用CMPR0,R1;比较R0,R17.多寄存器语句传输指令,LDM,STM类似于一次传一个BUFFER到寄存器当中,或反过来.后面一般要接一个地址改变方法nLDM从BUFFER传**多个寄存器传输**到LDMIAR0!,{R3-R9};加R0指向的地址上连续空间的**,保存到R3-R9当中,!表示R0值更新,IA后缀表示按WORD递增LDMFDSP!,{R0-R7,PC}^;恢复现场,异常处理返回,^表示不允许在用户模式下使用。nSTM从寄存器列表向存储空间传值。STMIAR1!,{R3-R9};将R3-R9的**存储到R1指向的地址上,R1值更新。STMFDSP!,{R0-R7,LR};现场保存,将R0~R7,LR入栈stmfdsp!,{r8-r9},把SP寄存器对庆的地址的值存到R8,R9当中.!表示最后的值写入SP中。Fd表示8.ARM指令的变形大部分指令后位可以接与S两个特殊位来表示,对CPSR特殊的一些判断S,表示当前指令执行后把结果改写CPSRsubs,Adds取决于具体条件,只有CPSR满足指定条件时才指这一指令BEQ实际上B+EQ的条件执行.addne表示ADD+NE才开始加.9.ARM指令的寻址方式寻址方式是根据指令中给出的地址码来**真实的地址,ARM中有9种寻址方法l寄存器寻址直接用寄存器编号来寻址,最为常用MOVR1,R2;R2->R1l立即数寻址即指令中的地址码是操作数本身,可以立即取出使用,立即数前带一个#表示,否则表示一个地址SUBSR0,R0,#1;R0-1->R0注意与SUBSR0,R0,1区别l寄存器偏移寻址这是ARM特有的寻址模式,当第2操作数是寄存器,在执行操作之前,可以做一次移位操作MOVR0,R2,LSL#3;R2的逻辑左移3位,结果放入R0,即R0=R2*8ANDSR1,R1,R2,LSLR3;RS的值左移R3位,然后和R1相与操作,结果放入R1移位操作有LSL(逻辑左移),LSR(逻辑右移),ASR(算术右移),ROR(循环右移)RRX带扩展的循环右移l寄存器间接寻址即寄存器中值是一个地址,用[]来取出**到地址当中LDRR2,[R0];把R0的值当成地址,取出相应值,赋给R2l基址寻址把寄存器的地址值加上一个偏移量LDRR2,[R3,#0x0F];R3中的值加上0x0F,从这个地址取出值赋给R@l相对寻址基址寻址的变形,由PC寄存器提供基准地址,指令中地址段作为偏移量.两者相加即是有效地址,以下是BL采用相对寻址BLNEXT…NEXT…MOVPC,LR;从子程序返回10.ADSARM的伪指令类似于C语言的宏,由汇编程序预处理.l符号定义指令全局变量定义GBLA,GBLL,GBLS局域变量定义LCLA,LCLL,LCLS变量赋值**TA,**TL,**TS其中上述伪指令中,最后面的A表示给一个算术变量赋值,L表示用于给一个逻辑变量赋值,s表示给一个字符串赋值GBLLcodedbg;声明一个全局的逻辑变量Codebg**TL{TRUE};设置变量为{TRUE}LCLAbitno;声明一个算术变量Bitno**TA8;设变量值为8l**定义伪指令nSPACE定义一个内存空间,并用0初始化{label}SPACEexprDataBufSPACE100;定义100字节长空间,unsignedcharDataBuf[100];nDCB定义一个连续字节内存空间,用伪指令的表达式expr来初始化.一般可以用定义**表格,或文字字符串.(这时等同于**TS),用于初始二进制BUFFER{label}DCBexpr{,expr…}DestDCB-120,20,36,55;等同于unsignedcharDest[]={-120,20,36,55};nDCU定义的一段字的内存空间(DCB是字节),并用后面表达式初始化_RE**TDCUReset;等同于DWORD_RE**T[]={Reset};nMAP定一个结构化内存,相当于定义一个C结构nFILED定义一个结构化内存的成员MAP0x00,R9;定义内存表,地址为R9TimerFIELD4;定义**域Timer,长为4字AttribFIELD4;定义**域Attrib,长为4字StringFILED100;定义**域String,长为100字相当于C语言的定义:struct{DWORDTimer;DWORDAttrib;CharString[100];}R9;11.杂项的伪指令n字节对齐ALIGNALIGN;声明4字节对齐n定义一个数字常量定义EQUNAMEEQUexpr{type}PLLCONEQU0xE01FC080;定义PLLCON,类似于C的宏或C++的常量n包含文件GET和INCLUDEINCLUDElpc2106.incnNOP空指令在汇编时会被ARM的空操作代替,比如MOVR0,R0,一般用于延时与占位。n声明一个外部符符号IMPORT,EXTERNIMPORT,EXTERN向外部导入一个符号,一般是外部程序全局变量n条件编译:[]。类似于C的#ifdef之类定义。格式:[条件表达式满足条件分支|不满足条件分支]示例1:[ENTRY_BUS_WIDTh**=32;类似#ifENTRY_BUS_WIDTh**=32bChangeBigEndian;DCD0xea000007];类似#endif示例2:[CLKDIV_VAL>1;类似#ifCLKDIV_VAL>1blMMU_SetAsyncBusMode|;类似#elseblMMU_SetFastBusMode;defaultvalue.];类似#endif示例3[Th**UMBCODE类似#ifdefTh**UMBCODEbxlr|;类似#elsemovpc,lr];类似#endifn段定义AREAn指令集定义CODE16和CODE32指示是Thumb指令集(压缩指令集,每个指令16位)。还是普通32位指令集n汇编结束:ENDn程序入口ENTRY