我的任务是获取一组数字并将其放入ARM程序集并执行2的补码,然后再次输出以供显示。我能够完成大部分工作,但输出告诉我它无法正常工作。
C代码:
#include <stdio.h>
int * comp( int a[], int size ) ;
void main( int argc, char * argv[] )
{
int array[] = { 1, -1, 252, -252, 0, 3015 } ;
int size = sizeof(array) / sizeof(int) ;
int * result ;
int i ;
result = comp( array, size ) ;
printf( "Original Complement\n" ) ;
for( i = 0 ; i < size ; i++ )
printf( "%d %d\n", array[i], *(result+i) ) ;
}
ARM程序集:
AREA |comp$code|, CODE, READONLY ; tell the assembler stuff
IMPORT malloc ; import malloc to be used
EXPORT comp ; tell the assembler to show this label to the linker
comp ; the label defining the entry point
stmfd sp!, {v1-v6, lr} ; standard entry
str v1, [a1] ; copy a1 over to v1
str v2, [a2] ; copy a1 over to v1
bl malloc ; clears pointer for new array
loop
ldr a4,[v1],#4 ; start going through loop starting at top or array
mvn a4, a4 ; ones complement
add a4,a4,#1 ; make it 2's complement
str a4,[a1], #4 ; move back into the array
subs v2, v2, #1 ; set a flag for the end of the loop
bne loop ; start again for the next value in the array
ldmfd sp!, {v1-v6, pc} ; puts all registers back into the caller
END
输出:
Original Complement
0 -442500552
-1 -442500552
252 0
-252 0
0 0
3015 0
任何人都可以帮我弄清楚为什么它会给我这么混乱的输出
答案 0 :(得分:4)
str v1, [a1] ; copy a1 over to v1
这会将寄存器v1
的未定义内容存储在a1
中传递的int数组的第一个元素上。您可以看到输出中原始数组中的第一个元素已被0
覆盖。
如果您想记住另一个注册表中的原始a1
,则可能意味着mov v1, a1
。
str v2, [a2] ; copy a1 over to v1
再次不是你的意思,但是a2
是小整数size
我很惊讶这种写入低内存的尝试不会立即崩溃!
bl malloc ; clears pointer for new array
你没有在这里传递你想要的内存量malloc
,它获取了int数组地址并将其视为一个字节数。假设32位int
,您希望mov a1, a2, asl#2
将int大小乘以4个字节。
您可能还应该检查它是否失败并返回NULL
。
ldmfd sp!, {v1-v6, pc} ; puts all registers back into the caller
结果寄存器a1
此时将指向其数组的末尾而不是开始。您需要存储malloc
的原始结果并将其返回此处。