We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
hi i created a hardware that calculates the square root of (a^2+b^2 )
i sent the inputs (a and b) with assembly and that was fine however when i tried to send them using c code the hardware take them as inputs calculates a^2 + b^2 but never do the square root
i am really clueless here i couldn't locate the problem
heeeeeeeeeeeeeeelp
So, if I understand correctly :
AGAIN LDR R1, =0x59000000 LDR R0, =0x00000022 STR R0, [R1] LDR R1, =0x59000000 LDR R0, =0x00002200 STR R0, [R1] B AGAIN ENDP
0x59000000 is the address where the input should be sent. I'll call it input_address here.
Then the first input value (a in your algebraic formulae) is retrieved from address 0x22 and stored at input_address.
Same thing for second input value (b), which address seems to be 0x2200.
Then, I guess, once two values provided the hardware do the whole calculation automatically ?
In that case, do this code work in your case :
test.c
int calculate(int a, int b) { volatile int *input_address = (int*)0x59000000; while(1) { *input_address = a; *input_address = b; } }
Compiling it with gcc like this :
armv7a-hardfloat-linux-gnueabi-gcc -O3 -nostdlib -shared -o test.o test.c
Generates this machine code :
armv7a-hardfloat-linux-gnueabi-objdump -d test.o
00000218 <calculate>: 218: e3a03459 mov r3, #1493172224 ; 0x59000000 21c: e5830000 str r0, [r3] 220: e5831000 str r1, [r3] 224: eafffffc b 21c <calculate+0x4>
Which is roughly the same.
In any case, in your provided code, did you try this instead :
int main() { the_old_days: xd[0]=0; yd[0]=0; int i; for(i=0;i<9;i++){ /* with i < 10, when i = 9, xd[i+1] will be equal to xd[10] which is out of bounds */ xd[i+1]= xd[i]+1; yd[i+1]= yd[i]+1; regdistance = xd[i]; regdistance = yd[i]; } goto the_old_days; }
as i told M
Peter Harris
I don't why my keil can't allocate a memory address with a pointer however i think that the problem is within the def of the "attribute" which allocate a fixed address that can't be reused by another
i tried to differentiate the output of yd and xd and when i compiled my code i observed that regdistance take only the value of xd so i defined another address memory to put the yd and when i simulate my hardware behavior i found that now it calculates the a^2+b^2 but not the square root
if anyone has a suggestion or any idea how can i resolve this prob please help
Well, can you use objdump -d on the bugged binary file and paste the output here.
I do not think that the variable definition is the problem here. However, one way to be sure is to try defining regdistance within main like this :
volatile int *regdistance = (int*)0x59000000;
And see if it works.
Note that you might want to replace
for (i = 0; i < 10; i++)
by
for (i = 0; i < 9; i++)
else you will write into places you did not define (xd[9+1] is not defined).
However, the "at" behaviour can also be emulated doing something like :
volatile int input_address __attribute__ ((section ("regdistance"))); int calculate(int a, int b) { while(1) { input_address = a; input_address = b; } }
Using a linker script like this :
test.ld
ENTRY(calculate)SECTIONS{ . = 0x10000; .text : { *(.text*) } . = 0x59000000; .regdistance : { *(regdistance*) }}
ENTRY(calculate)
SECTIONS
{
. = 0x10000;
.text : { *(.text*) }
. = 0x59000000;
.regdistance : { *(regdistance*) }
}
And then compile like this :
armv7a-hardfloat-linux-gnueabi-gcc -O3 -nostdlib -mthumb -T test.ld -o test test.c
Code produced :
LANG=C armv7a-hardfloat-linux-gnueabi-objdump -d testtest: file format elf32-littlearmDisassembly of section .text:
LANG=C armv7a-hardfloat-linux-gnueabi-objdump -d test
test: file format elf32-littlearm
Disassembly of section .text:
00010000 <calculate>: 10000: f240 0300 movw r3, #0 10004: f6c5 1300 movt r3, #22784 ; 0x5900 10008: 6018 str r0, [r3, #0] 1000a: 6019 str r1, [r3, #0] 1000c: e7fc b.n 10008 <calculate+0x8> 1000e: bf00 nop