arm蛋疼汇编 part8 -- 汇编 c 谁调用谁?时间:2022-03-16 01:06:11今晚学校网络真无法忍受了 哎~ 只能直接上代码了:makefile: test.bin: test arm-2440-linux-gnueabi-objcopy -I elf32-littlearm test -O binary test.bin cp test.bin ../../ test: test.o test2.o arm-2440-linux-gnueabi-ld -Ttext=0x30000000 test.o test2.o -o test test2.o: test2.c arm-2440-linux-gnueabi-gcc -c test2.c -o test2.o test.o: test.S arm-2440-linux-gnueabi-as test.S -o test.o clean: rm -f test.o test test.bin test2.o ../../test.bin arm-2440-linux-gnueabi-ld -Ttext=0x30000000 test.o test2.o -o test test2.o: test2.c 这里链接只能使用ld 如果使用gcc连接的话 会链接ctr*.o文件 提示找不到main函数 如下: arm-2440-linux-gnueabi-as test.S -o test.o arm-2440-linux-gnueabi-gcc -c test2.c -o test2.o test2.c:1: warning: initialization makes pointer from integer without a cast arm-2440-linux-gnueabi-gcc -Ttext=0x30000000 test.o test2.o -o test test.o: In function `_start': (.text+0x0): multiple definition of `_start' /home/leftover-crazy/arm/arm-2440-linux-gnueabi/arm-2440-linux-gnueabi//sys-root/usr/lib/crt1.o:init.c:(.text+0x0): first defined here /home/leftover-crazy/arm/arm-2440-linux-gnueabi/arm-2440-linux-gnueabi//sys-root/usr/lib/crt1.o: In function `_start': init.c:(.text+0x24): relocation truncated to fit: R_ARM_CALL against symbol `__libc_start_main@@GLIBC_2.4' defined in .plt section in /home/leftover-crazy/arm/arm-2440-linux-gnueabi/arm-2440-linux-gnueabi//sys-root/usr/lib/crti.o init.c:(.text+0x28): relocation truncated to fit: R_ARM_CALL against symbol `abort@@GLIBC_2.4' defined in .plt section in /home/leftover-crazy/arm/arm-2440-linux-gnueabi/arm-2440-linux-gnueabi//sys-root/usr/lib/crti.o init.c:(.text+0x30): undefined reference to `main' /home/leftover-crazy/arm/arm-2440-linux-gnueabi/arm-2440-linux-gnueabi//sys-root/usr/lib/crti.o: In function `call_gmon_start': /home/leftover-crazy/arm/crosstool-ng-1.8.1_build/targets/arm-2440-linux-gnueabi/build/build-libc/csu/crti.S:32: relocation truncated to fit: R_ARM_PLT32 against undefined symbol `__gmon_start__' /home/leftover-crazy/arm/arm-2440-linux-gnueabi/arm-2440-linux-gnueabi//sys-root/usr/lib/crti.o: In function `_init': /home/leftover-crazy/arm/crosstool-ng-1.8.1_build/targets/arm-2440-linux-gnueabi/build/build-libc/csu/crti.S:54: relocation truncated to fit: R_ARM_PLT32 against `call_gmon_start' /home/leftover-crazy/arm/arm-2440-linux-gnueabi/arm-2440-linux-gnueabi//sys-root/usr/lib/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init': elf-init.c:(.text+0x18): relocation truncated to fit: R_ARM_PLT32 against symbol `_init' defined in .init section in /home/leftover-crazy/arm/arm-2440-linux-gnueabi/arm-2440-linux-gnueabi//sys-root/usr/lib/crti.o /home/leftover-crazy/arm/arm-2440-linux-gnueabi/lib/gcc/arm-2440-linux-gnueabi/4.3.2/../../../../arm-2440-linux-gnueabi/bin/ld: BFD (GNU Binutils) 2.19.1 assertion fail /home/leftover-crazy/arm/crosstool-ng-1.8.1_build/targets/src/binutils-2.19.1/bfd/elf32-arm.c:10414 /home/leftover-crazy/arm/arm-2440-linux-gnueabi/lib/gcc/arm-2440-linux-gnueabi/4.3.2/../../../../arm-2440-linux-gnueabi/bin/ld: BFD (GNU Binutils) 2.19.1 assertion fail /home/leftover-crazy/arm/crosstool-ng-1.8.1_build/targets/src/binutils-2.19.1/bfd/elf32-arm.c:10414 /home/leftover-crazy/arm/arm-2440-linux-gnueabi/lib/gcc/arm-2440-linux-gnueabi/4.3.2/../../../../arm-2440-linux-gnueabi/bin/ld: BFD (GNU Binutils) 2.19.1 assertion fail /home/leftover-crazy/arm/crosstool-ng-1.8.1_build/targets/src/binutils-2.19.1/bfd/elf32-arm.c:10414 test2.c: void (*show2)(char *, ...) = 0x33f9303c; //定义指向0x33f9303c的函数指针 即uboot中printf函数的指针 void test2(void) { const char *str = "hello uboot c call asm !/n"; show2("hello uboot asm call c !/n"); //调用printf打印 test3(str); //调用test.S中的test3函数 str保存到r0中 注意这里传递给r0的是地址 } test.S: .section .text .global _start .global test3 @汇编中的标号都必须导出 不然仅是本文件可见 _start: mov ip,sp stmfd sp!, {fp, ip, lr, pc} sub fp, ip, #4 @以上三行保护现场 bl test @调用汇编函数test bl test2 @调用c函数test2 sub sp, fp, #12 ldmfd sp, {fp, sp, pc} @以上两行执行恢复现场操作 并返回 test: mov ip, sp stmfd sp!, {fp, ip, lr, pc} sub fp, ip, #4 ldr r0, =hello @取出hello的地址存入r0作为uboot中printf函数的第一个参数 mov lr, pc @保存函数返回地址 pc总是指向当前指令的下两行代码即函数返回时首先执行sub sp,fp, #12 ldr pc, show @将show的值保存到pc中,实现uboot中printf函数的调用 sub sp, fp, #12 ldmfd sp, {fp, sp, pc} test3: mov ip, sp stmfd sp!, {fp, ip, lr, pc} sub fp, ip, #4 @该函数被c调用参数已在c语言调用的时候传入 mov lr, pc ldr pc, show sub sp, fp, #12 ldmfd sp, {fp, sp, pc} show: .word 0x33f9303c @uboot中printf函数的地址 hello: .asciz "hello uboot asm call asm !/n" 执行结果: Fantasy >go 30000000 ## Starting application at 0x30000000 ... hello uboot asm call asm ! hello uboot asm call c ! hello uboot c call asm ! ## Application terminated, rc = 0x0 Fantasy > *说明一下:汇编中其实没有函数的概念 所有的都是标号 不管是常量标号还是函数标号 在连接的时候都是等同的 所以相互调用的时候应该注意函数与变量 常量的区别 不然可能会出现编译链接正常 但是执行时却出错的冏像