GNU内联汇编
1、把1c.c程序补充完整,以便得到a+b值,只能在()中填入相关的汇编代码,该值最后存于0x20009000处。1c.c程序如下:
void _start( void )
{
int a = 30;
int b = 48;
int sum = 0;
__asm__ __volatile__(
);
*(( int * )(0x20009000)) = sum;
}
答案:
void _start( void )
{
__asm__ __volatile__("ldr sp,=0x20000000\n"
:
:
);
int a = 30;
int b = 48;
int sum = 0;
__asm__ __volatile__(
"ldr r0,%2\n"
"add %0,%1,r0\n"
:"=r"(sum)
:"r"(a),"m"(b)
);
*(( int * )(0x20009000)) = sum;
}
2、用c编写程序2c.c,在c中实现函数 usigned lrsp(int flag),当flag=1时返回寄存器lr的值,为0时,返回寄存器sp的值。并在主程序中调用函数lrsp(0),将返回结果写入内存0x20009000处。
答案:
init.s:
ldr sp,=0x20008000
ldr pc,=_start
2c.c:
unsigned lrsp(int flag);
void _start(void)
{
unsigned r;
r=lrsp(0);
*(( int * )(0x20009000)) = r;
}
unsigned lrsp(int flag)
{
unsigned result;
__asm__ __volatile__(
"ldr r0,%1\n"
"cmp r0,#1\n"
"moveq %0,lr\n"
"cmp r0,#0\n"
"moveq %0,sp\n"
:"=r"(result)
:"m"(flag)
);
return result;
}
3、已知uboot将printf函数加载到内存地址为0x2fd17b18处,编写汇编程序3s.S,调用printf,打印出hello world!
答案:
思路:
1) 将“hello world!”地址入 r0
2)将返回地址入lr
3)执行 ldr pc,=0x2fd17b18
.global _start
_start:
mov r4,lr
ldr r5,=0x2fd17b18
ldr r0,=mystr
mov lr,pc
mov pc,r5
mov lr,r4
b .
mystr:
.string "hello world!\n"
.end
4、将下面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);
}
答案:
.global _start
_start:
push {lr}
ldr r0,=mystr
ldr r1,a
ldr r2,p
ldr r3,c
ldr r4,d
push {r4}
ldr r5,e
push {r5}
ldr r6,=0x2fd17b18
mov lr,pc
mov pc,r6
pop {r4,r5}
pop {lr}
b .
a: .word 1
p: .word 2
c: .word 3
d: .word 4
e: .word 5
mystr:
.string "\na=%d,b=%d,c=%d,d=%d,e=%d\n"