环境:ADS
软件:Metrowerks CodeWarrior for ARM Developer Suite v1.2
注意:汇编文件.s的名称不能和c文件.c的名称相同,因为他们需要生成各自的.o文件。
要求:用C语言和汇编语言混合编程实现:在C语言程序中调用汇编语言代码,完成字符串STR1与STR2内容的互换(假设STR1和STR2长度一致)。
C语言:
# includeextern 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语言:
# includeextern 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语言:
# includeextern 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语言:
# includeextern 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



