On Thu, Jan 10, 2002 at 11:53:44PM -0500, Lam Yick Yan wrote:
> I am a C programmer, and now I got a task to write assembly
> language (in Linux enviroment) for some time crucial function....
>
> I am not very familiar with gcc. I have written
> the following very simple function, it compiles successfully. However
> when I run it, I got segmentation fault....
>
[snip]
> The mul fuction is written in Assembly (mul.S) as follow:
> (not finished Yet, just simple function doing nothing)
> ----------------------------------------------------------------------
> .text
> .align
>
> .global mul
> .global _mul
>
> mul:
> _mul:
> stmdb sp!, {r4-r12, lr} @ push everything onto the stack...
> adr r0, Rm_backup
> str r1, [r0]
> ldmia sp!, {r4-r12, pc} @ return with <lr> destroyed
This is slow. You first push everything on the stack, then do the
actual computation and then then restore everything again. It's *much*
faster to use inline assembly in this case, especially if the
computation is indeed simple. There are two excellent inline assembly
links on the kernelnewbies links page, see:
http://www.kernelnewbies.org/links/
and look for "assembly". The links are about x86 assembly, but it also
applies to arm assembly.
> The Makefile is
> ---------------------------------------------------------------------------
> CC=arm-linux-gcc
> CFLAGS= -Wall -O \
> -fforce-mem -fforce-addr -fthread-jumps -fcse-follow-jumps \
> -fcse-skip-blocks -fexpensive-optimizations -fregmove\
> -fschedule-insns2 -fstrength-reduce -finline-functions\
> -fomit-frame-pointer
Ehm, don't do that, not all combinations of compiler flag are valid.
You'd better use -O2 or -Os combined with -fomit-frame-pointer and the
correct architecture parameters (-march=armv4 -mtune=strongarm1100 for
SA11x0 systems).
> all: main
>
> main: mul.o main.o
> $(CC) $(CFLAGS) -o main mul.o main.o
>
> main.o: main.c
> $(CC) $(CFLAGS) -c main.c -o main.o
Let me introduce you to implicit makefile rules. This implicit rule
will tell make how to make .o files from .c files:
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
> mul.o: mul.S
> $(CC) $(CFLAGS) -c mul.S -o mul.o
Same for .S files:
.S.o:
$(CC) $(CFLAGS) -c $< -o $@
> The intention in mul.S is to declare 3 local variables,
> Rm_backup, Rs_backup and ip_backup and store value of r1 into it
> but when I run, I got segmentatin fault immediately. Why???
Let the program dump core (limit coredumpsize unlimited in tcsh, ulimit
-c unlimited in bash), run it through a debugger (gdb main core) to
get a backtrace (bt) and you'll see exactly why it went wrong.
> Another question: can someone tell me how can I implement the
> following C functions in ARM assembly language:
>
> 1) long mul(long a, long b, long *c, long *d) {
> long e=3;
>
> *c=a+e;
> *d=*c;
> return *d;
> }
Try "arm-linux-gcc -g -O2 -c foo.c -o foo.o", run "arm-linux-objdump -D
-S foo.o | less" and you'll see how to do it.
Erik
--
J.A.K. (Erik) Mouw, Information and Communication Theory Group, Faculty
of Information Technology and Systems, Delft University of Technology,
PO BOX 5031, 2600 GA Delft, The Netherlands Phone: +31-15-2783635
Fax: +31-15-2781843 Email: [EMAIL PROTECTED]
WWW: http://www-ict.its.tudelft.nl/~erik/
_______________________________________________
http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm
Please visit the above address for information on this list.