如何解决如何用汇编语言找到给定值的最大值和变量的地址?
我正在学习ARMv7,问题是要实现以下代码:
shvar = max(shvar,x)
变量x的值为R2,shvar的地址在R1中。我的问题是,shvar本质上是一个指针,并且我需要“取消引用”它,也就是获得它指向内存中的值吗?
我做了类似的事情:
LDR R3,[R1]
...
旁注:我的教练说:“再次从内存中读取您已经在R3中拥有的值是不好的”,我想知道他是否在指这个。
解决方法
unsigned int max ( unsigned int,unsigned int );
unsigned int test ( void )
{
return(max(4,5)+1);
}
00000000 <test>:
0: e92d4010 push {r4,lr}
4: e3a01005 mov r1,#5
8: e3a00004 mov r0,#4
c: ebfffffe bl 0 <max>
10: e2800001 add r0,r0,#1
14: e8bd8010 pop {r4,pc}
调用约定与目标(armv7-a)和编译器作者的选择结合在一起。编译器可以创建/选择自己的调用约定,如果目标供应商有一个abi,那么他们不必遵循目标供应商的推荐abi。
上面是gcc,您可以看到第一个参数32位(或更少)进入r0,第二个参数进入r1。结果返回到r0。
unsigned int max ( unsigned int *,unsigned int );
unsigned int test ( void )
{
return(max((unsigned int *)4,pc}
所以没有区别,位是位地址,高级语言也是如此
unsigned int * test ( unsigned int *p )
{
return(++p);
}
00000000 <test>:
0: e2800004 add r0,#4
4: e12fff1e bx lr
当用作少数几个时钟的地址时,它只是一个地址,这意味着某些东西随后又回到位。
unsigned int test ( unsigned int *p )
{
return(*p);
}
00000000 <test>:
0: e5900000 ldr r0,[r0]
4: e12fff1e bx lr
对于ARM,建议将调用约定r0-r3视为易失性的,它们已在函数中使用,但函数不必保留其状态。如果合适,则返回值返回r0。因此,如果编译器使用了该约定,则r3完全有效。但是,如果这不是回报的一部分(即使有可能),也欢迎您
ldr r3,[r1]
,但是在函数返回之前,您使用r3的所有内容都希望折回到返回值中,或者该函数的功能是什么。因此,如果您想通过地址说出基准,则可以这样做
unsigned int test ( unsigned int timerregaddress,unsigned int numloops );
您可以这样做
ldr r2,[r0] @ read timer
loop:
@ code under test
subs r1,r1,#1
bne loop
ldr r3,[r0] @ read timer
sub r0,r3,r2 @ compute difference in time
bx lr
如果被测代码不使用这些寄存器中的任何一个(几乎您所使用的任何寄存器都需要在函数的开头和结尾处被压入并弹出),那么r2和r3将是中间变量的自然选择
我怀疑注释与您未向您显示的代码有关,因为您可能没有再使用r3来丢失此负载下存储在其中的内容。
a = x + y;
a = 37 + z;
虽然编译器可能会生成第一行,但第二行会破坏变量a中的内容,就像这样做
mov r3,#5
ldr r3,[r1]
因此,您需要查看所有代码,而不是发送给我们的一行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。