第九章:汇编例题

来源:互联网 发布:maya arnold2018 mac 编辑:程序博客网 时间:2024/05/06 16:56

例9.1 实现两个64位数相加的汇编程序。
STACK_TOP EQU 0X00002000 ;定义栈顶并初始化化
AREA RESET,CODE ;开辟代码区,进入映像文件启动
DCD STACK_TOP ;分配一段内存空间
DCD START
ENTRY ;程序入口
START
LDR R0,=data1
LDR R1,[R0]
LDR R2,[R0,#4]
LDR R0,=data2
LDR R3,[R0]
LDR R4,[R0,#4]
ADDS R6,R2,R4
ADC R5,R1,R3
LDR R0,=result
STR R5,[R0]
STR R6,[R0,#4]
data1 DCD 0X11223344,0xFFDDCCBB
data2 DCD 0X11223344,0xFFDDCCBB
result DCD 0,0
END

例9.2 实现8位数到16位数扩展的汇编程序
STACK_TOP EQU 0x00002000
AREA reset,CODE
DCD STACK_TOP
DCD Start
ENTRY
Start

LDR R0,data
LDR R1,mask
MOV R2,R0,LSR #4
MOV R2,R2,LSL #8
AND R0,R0,R1
ADD R0,R0,R2
STR R0,[R3]
data DCB 0xFC
ALIGN
mask DCD 0x000F
END

9.3 实现查找最大值的汇编程序
STACK_TOP EQU 0X00002000
AREA RESET,CODE
DCD STACK_TOP
DCD START
ENTRY
START
LDR R0,data1
LDR R1,data2
CMP R0,R1
BHI save
MOV R0,R1
save STR R0,[R2]
data1 DCD 0X400
data2 DCD 0X200
END

9.4 实现根据参数改变运算方式的汇编程序。
STACK_TOP EQU 0X00002000
AREA RESET,CODE
DCD STACK_TOP
DCD START
ENTRY
START
MOV R0,#1
MOV R1,#3
MOV R2,#2

arithfunc
CMP R0,R6
LDR R6,num
num
integer
BHI outofrange
ADR R3,JUMPTABLE
LDR R5,[R3,R0,LSL#2]
JUMPTABLE
DCD DOADD
DCD DOSUB1
DCD DOSUB2
DOADD
ADD R0,R1,R2
B save
DOSUB1
SUB R0,R1,R2
B save
DOSUB2
SUB R0,R2,R1
B save
outofrange
MOV R0,#0XFF
save
STR R0,[R4]

     END

9.5 冒泡算法汇编程序。
STACK_TOP EQU 0X00002000
AREA RESET,CODE
DCD STACK_TOP
DCD START

Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
ENDP
ENTRY
START
MOV R4,#0
LDR R6,=SRC
ADD R6,R6,#len
outer
LDR R1,=SRC
inner
LDR R2,[R1]
LDR R3,[R1,#4]
CMP R2,R3
STRGT R3,[R1]
STRGT R2,[R1,#4]
ADD R1,R1,#4
CMP R1,R6
BLT inner

ADD R4,R4,#4
CMP R4,#len
SUBLE R6,R6,#4
BLE outer
AREA ARRAY,DATA,READWRITE
SRC DCD 2,4,10,8,14,1,20
len EQU 7*4
END

例9.6 调用子程序实现求1到N只和的汇编程序。
STACK_TOP EQU 0X00002000
AREA RESET,CODE
DCD STACK_TOP
DCD START
ENTRY
START
ENTRY
MOV R0,#100
MOV R1,#0
LOOP
ADD R1,R1,R0
SUBS R0,R0,#1
CMP R0,#0
BNE LOOP
LDR R2,=RESULT
STR R1,[R2]
RESULT
DCD 0
STOP
B STOP
NOP
END

例9.7调用汇编函数实现字符串复制的c程序。
c语言程序

include

include “stm32f10x.h”

extern void strcopy(char *d,const char *s); //引入外部函数
int main()
{
const char *srcstr=”First string-soure”;
char detstr[]=”Second string - destination”;

printf("Before copying:\n");

printf(” ‘%s’\n ‘%s’\n”,srcstr,detstr);
strcopy(detstr,srcstr); //使用汇编函数
printf(“Before copying:\n”);
printf(” ‘%s’\n ‘%s’\n”,srcstr,detstr);
return 0;
}

汇编程序
STACK_TOP EQU 0X00002000
AREA SCOPY,CODE
DCD STACK_TOP
DCD START
ENTRY
START
EXPORT strcopy ;导出函数
strcopy ;定义一个标示符,相当于一个函数,实现复制功能
LDRB R2,[R1],#1
STRB R2,[R0],#1
CMP R2,#0
BNE strcopy
MOV pc,lr
END

这是一个c语言调用汇编的例子,功能是为了实现字符串的拷贝,其中汇编文件为字符串拷贝的功能子函数。在这里需要说明的是c语言调用汇编语言的一些基本规则,首先是参数传递的规则,c语言的函数前4个参数通过R0-R3来传递,其它参数通过堆栈(FD)传递,且这种传递是单项的,即汇编语言中的R0-R3的值不会再回传给c语言。拿例3举例来说,当在语言中调用strcopy(dststr,srcstr);时,字符串dststr的首地址将会传给r0,srcstr的首地址将会传给r1,当汇编语言拿到这两个寄存器时,就会通过地址依次加1的形式进行地址内容的复制也就是字符串的复制,当复制到最后一个字母e时,通过比较r2寄存器中的值是否为0来判断是否调出汇编程序(因为在c语言中声明字符串时末尾被自动的添加了一个),这里需要注意的是,此时寄存器r0的值为指向源字符串末尾的’’的地址值,而寄存器r1的值为指向已经拷贝过的目的字符串中的”e”的地址值,当调出汇编程序时,r0,r1这两个值将不会回传给strcopy(dststr,srcstr);中的两个参数dststr和srcstr,这两个参数的值仍然是c语言在初始化这两个字符串时指向字符串的首地址,这一点可以通过ATX调试时观察寄存器的变化情况来证明。但是为什么地址值没有变化,但却实现了字符串的拷贝了呢?这主要时因为通过汇编程序,虽然没有改变两个指针的位置,但却改变了两个字符串所在内存地址中的内容,这种方式就是c语言中常说的引用方式,即dststr和r0起初指向的是同一内存空间,但是字符串复制时只是利用r0来复制的,而dststr的位置却没有发生变化。因此在c语言中输出字符串时并不需要将dststr减去字符串的个数来实现指向字符串的首地址。

例9.8 调用C函数的汇编程序。实现i+2*i+3*i+4*i+5*i
汇编程序:
STACK_TOP EQU 0X00002000
PRESERVE8
AREA RESET,CODE
DCD STACK_TOP
DCD START
ENTRY
START
IMPORT g
str lr,[sp,#-4]!
MOV R0,#2
ADD R1,R0,R0
ADD R2,R1,R0
ADD R3,R1,R2
STR R3,[sp,#-4]!
ADD R3,R1,R1
BL g
ADD sp,sp,#4
LDR pc,[sp],#4
END

C程序
int g(int a,int b,int c,int d,int e)
{
return a+b+c+d+e;
}

例9.9在c语言程序中内嵌汇编程序实现字符串复制。

include “stm32f10x.h”

include

include “stm32f10x.h”

include

0 0