栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

嵌入式汇编实验三

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

嵌入式汇编实验三

嵌入式汇编实验三

环境:ADS
软件:Metrowerks CodeWarrior for ARM Developer Suite v1.2
注意:汇编文件.s的名称不能和c文件.c的名称相同,因为他们需要生成各自的.o文件。

一、交换字符串

要求:用C语言和汇编语言混合编程实现:在C语言程序中调用汇编语言代码,完成字符串STR1与STR2内容的互换(假设STR1和STR2长度一致)。

C语言:

# include 
extern void swap(char *d,char *s);

int main() {
	char *str1 = "AAAAA";
	char *str2 = "BBBBB";
	printf("Before swaping:n");
	printf("%sn%sn", str1, str2);
	swap(str1, str2);
	printf("After swaping:n");
	printf("%sn%sn", str1, str2);
	return(0);
}

汇编语言:

	AREA Swap,CODE,READonLY
	EXPORT swap

swap
	LDRB R2,[R0]
	LDRB R3,[R1]
	STRB R2,[R1]
	STRB R3,[R0]
	ADD R0,R0,#1
	ADD R1,R1,#1
	CMP R2,#0
	BNE swap
	MOV PC,LR
	END
二、排序

要求:用C语言和汇编语言混合编程实现:在C语言程序中调用汇编语言代码,将输入的20个字节数据,从大到小加以排序,大数在前,小数在后。

C语言:

# include 
extern void rank(char *s);

int main() {
	char *str = "ABCDEFGHIJKLMNOPQRST";
	printf("Before ranking:n");
	printf("%sn", str);
	rank(str);
	printf("After ranking:n");
	printf("%sn", str);
	return(0);
}

汇编语言:

	AREA Rank,CODE,READonLY
	EXPORT rank

rank				; 冒泡排序

	MOV R1,#19		; R1:外层循环次数
	
loop1				; 外循环
	
	MOV R0,R4
	MOV R2,#19		; R2:内层循环次数
		
loop2				; 内循环
		
	LDRB R3,[R0],#1
	LDRB R5,[R0]
	MOV R6,PC		; 保存PC地址
	ADD R6,R6,#8
	CMP R3,R5
	BLO swap
	SUB R2,R2,#1
	CMP R2,#0
	BNE loop2
			
	SUB R1,R1,#1
	CMP R1,#0
	BNE loop1
	
	MOV PC,LR
	
swap

	MOV R7,R3
	MOV R3,R5
	MOV R5,R7
	STRB R3,[R0,#-1]
	STRB R5,[R0]
	MOV PC,R6

	END

假设 MOV R6,PC 这条指令的地址是0x00008000,执行语句后 R6 的值变为 0x00008008 ,PC 的值变为0x00008004,也就是说在用MOV指令传递 PC 值的时候会现将 PC 的值 +8 后在传值。

C程序在调用汇编程序时,选用 R0~R3 进行传参,R4~R7 用作记录 R0~R3 的初始地址,以保证 R0~R3 的值改变后能正常返回,所以此题中用了 R0 传递字符串,R4 记录的 R0 的一开始的地址,不能去修改它,所以不用 R4。

三、访问全局变量

要求:用C语言和汇编语言混合编程实现:用汇编语言完成对C语言全局变量的访问。假设CVAR1和CVAR2是C语言中定义的全局变量,请用一段汇编语言访问它们,完成两者的相加运算,结果存放在CVAR1中。

C语言:

# include 
extern void test3();
unsigned int CVAR1 = 1;
unsigned int CVAR2 = 5;

int main() {
	printf("Before adding:n");
	printf("%dn", CVAR1);
	test3();
	printf("After adding:n");
	printf("%dn", CVAR1);
	return(0);
}

汇编语言:

	AREA Test3,CODE,READonLY
	EXPORT test3
	import CVAR1
	import CVAR2

test3

	LDR R0,=CVAR1
	LDR R1,=CVAR2
	LDR R2,[R0]
	LDR R3,[R1]
	ADD R2,R2,R3
	STR R2,[R0]
	MOV PC,LR
	END
四、函数调用

要求:用C语言和汇编语言混合编程实现:利用汇编语言程序调用C语言子程序的方式来求 i+ 2i + 3i +4i + 5i +6*i的和(设i为一个整型常数)。

C语言:

# include 
extern int g(int a, int b, int c, int d, int e, int f) {
	return a+b+c+d+e+f;
}

汇编语言:

	AREA f,CODE,READonLY
	EXPORT f
	import g
	ENTRY
	
start

	MOV R0,#1		;i的值
	ADD R1,R0,R0	;计算i*2
	ADD R2,R1,R0	;计算i*3
	ADD R3,R1,R2	;计算i*5
	STR R3,[SP,#-4]!
	ADD R3,R2,R2	;计算i*6
	STR R3,[SP,#-4]!
	ADD R3,R1,R1	;计算i*4
	BL g
	END

本题中需要传递 6 个参数,R0~R3 不够用,于是将多出来的 i * 5 和 i * 6 压入堆栈中,假设 SP 堆栈指针的初始值为 0x00000000,压入 i * 5 后,地址 0xFFFFFFFC 的值为 i * 5,SP 的值为 0xFFFFFFFC,接着压入 i * 6,SP 的值变为 0xFFFFFFF8,地址中的值为 i * 6

在调用函数的时候,R0~R3 分别传入 a~d 变量中,堆栈的传参是从小地址开始,先把地址为0xFFFFFFF8中的 i * 6 传入变量 d ,然后把地址 0xFFFFFFFC 中的 i * 5 传入变量 e

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/385058.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号