GNU内联汇编

307 阅读2分钟
  1. 把1c.c程序补充完整,以便得到a+b值,只能在()中填入相关的汇编代码,该值最后存于0x20009000处。1c.c程序如下:
// GNU 风格的内联汇编语法如下:
asm volatile ("asm code"
:output
:input
:changed
);

void _start(void)
{
    int a = 30;
    int b = 48;
    int sum = 0;
    __asm__ __volatile__(
    	"mov r0, %1\n"
    	"mov r1, %2\n"
    	"add %0, r1, r2\n"
    	:"=r"(sum) 	// 结果  =r 表示只写
    	:"r"(a),"r"(b) // 参数 r 使用任意通用寄存器
    );
    *((int *)(0x20009000)) = sum;
}
  1. 用c编写程序2c.c,在c中实现函数 usigned lrsp(int flag),当flag=1时返回寄存器lr的值,为0时,返回寄存器sp的值。并在主程序中调用函数lrsp(0),将返回结果写入内存0x20009000处。
unsigned lrsp( int flag );
void _start(void)
{
   unsigned val;
   val 			=	lrsp(0);
   *(int*)0x20009000	=	val;
}
unsigned lrsp( int flag )
{
   unsigned val;
   if( flag == 1 )
   {
   	__asm__ __volatile__(

   	"mov %0,lr\n"
   	:"=r"(val)
   	:
   	);

   }
   else if( flag == 0 )
   {
   	__asm__ __volatile__(
   	
   	"mov %0,sp\n"	
   	:"=r"(val)
   	:
   	);
   }
   else
   {
   	 val = -1;
   }
   return val;
}
  1. 已知uboot将printf函数加载到内存地址为0x2fd17b18处,编写汇编程序3s.S,调用printf,打印出hello world!
.global _start
_start:
   push {lr}
   ldr r4, =0x2fd17b18
   ldr r0, =mystr
   mov lr,pc
   mov pc,r4
   pop {lr}
   mov pc, lr
mystr: 
   .string "hello world!\n"
.end
  1. 将下面c程序改成汇编程序4s.S,已知uboot将printf函数加载到内存地址为0x2fd17b18处。
void _start( void )
{
   int a=1,b=2,c=3,d=4,e=5;
   printf(“\na=%d,b=%d,c=%d,d=%d,e=%d\n”,a,b,c,d,e);
}

4s.S

.global _start
_start:
	push {lr}
	ldr r0, =mystr
	ldr r1, a
	ldr r2, b
	ldr r3, c
	ldr r4, d
	push {r4}
	ldr r4, e
	push {r4}
	
	ldr r5,=0x2fd17b18
	mov lr,pc #调用函数前先保存pc
	mov pc,r5 # 执行函数
	pop {r4,r4}
	pop {lr}
	mov pc,lr
	
a: .word 1
b: .word 2
c: .word 3
d: .word 4
e: .word 5
mystr: .string "\na=%d,b=%d,c=%d,d=%d,e=%d\n"