; divide function written in ARM assembler ; signature: int divasm(int a, int b); AREA |C$$code|, CODE, READONLY |x$codeseg| EXPORT divasm divasm ; enters with a and b in registers a1 and a2 MOV a3,#1 ; a3=Rcnt from lecture divasm1 CMP a2,#0x80000000 ; shift a2 left until top bit set CMPCC a2,a1 ; ...or a2>a1 MOVCC a2,a2,ASL#1 ; shift a2 left if required MOVCC a3,a3,ASL#1 ; shift a3 left if required BCC divasm1 ; repeat whilst more shifting required MOV ip,#0 ; ip used to store result divasm2 CMP a1,a2 ; test for possible subtraction SUBCS a1,a1,a2 ; subtract if a1>a2 ADDCS ip,ip,a3 ; put relivant bit into result MOVS a3,a3,LSR#1 ; shift control bit MOVNE a2,a2,LSR#1 ; halve unless finished BNE divasm2 ; loop if there is more to do MOV a1,ip ; return result in register a1 MOV pc,lr ; return from the subroutine |x$dataseg| END
#include/* Simple test program for divasm.s and a C equivalent */ /* compile using 'armcc -li testdiv.c divasm.s */ /* Simon Moore */ extern int divasm(int a, int b); int divc(int a,int b) { int r; int t=1; while( (b&0x40000000) == 0 ) { /* fails if b=0 */ b=b<<1; t=t<<1; } r=0; do { if((a-b)>=0) { a=a-b; r=r+t; } b=b>>1; t=t>>1; } while(t!=0); return r; } int main( int argc, char **argv ) { int i,j,k; for(i=1; i<64; i+=3) { j=divasm(1234,i); k=divc(1234,i); printf("1234/%2d = %4d %s",i,j,(1234/i)==j ? "....correct" : "ERROR!!! "); printf(" = %4d %s\n",k,(1234/i)==k ? "....correct" : "ERROR!!! "); } return 0; }
; generated by Norcroft ARM C vsn 4.62 (Advanced RISC Machines) [May 04 1994] AREA |C$$code|, CODE, READONLY |x$codeseg| EXPORT divc divc MOV a3,#1 TST a2,#&40000000 BNE |L00001c.J5.divc| |L00000c.J4.divc| MOV a2,a2,LSL #1 MOV a3,a3,LSL #1 TST a2,#&40000000 BEQ |L00000c.J4.divc| |L00001c.J5.divc| MOV a4,#0 |L000020.J8.divc| SUBS ip,a1,a2 MOVPL a1,ip ADDPL a4,a4,a3 MOV a2,a2,ASR #1 MOVS a3,a3,ASR #1 BNE |L000020.J8.divc| MOV a1,a4 MOV pc,lr IMPORT __rt_stkovf_split_small IMPORT divasm IMPORT __rt_sdiv IMPORT _printf EXPORT main main MOV ip,sp STMDB sp!,{v1-v4,fp,ip,lr,pc} SUB fp,ip,#4 CMP sp,sl BLLT __rt_stkovf_split_small MOV v2,#1 |L000058.J4.main| MOV a2,v2 MOV a1,#&d2 ADD a1,a1,#&400 BL divasm MOV v4,a1 MOV a2,v2 MOV a1,#&d2 ADD a1,a1,#&400 BL divc MOV v3,a1 MOV a1,v2 MOV a2,#&d2 ADD a2,a2,#&400 BL __rt_sdiv MOV v1,a1 TEQ a1,v4 ADDNE a4,pc,#L0000dc-.-8 ADDEQ a4,pc,#L0000e8-.-8 MOV a3,v4 MOV a2,v2 ADD a1,pc,#L0000f4-.-8 BL _printf TEQ v1,v3 ADDNE a3,pc,#L0000dc-.-8 ADDEQ a3,pc,#L0000e8-.-8 MOV a2,v3 ADD a1,pc,#L000108-.-8 BL _printf ADD v2,v2,#3 CMP v2,#&40 BLT |L000058.J4.main| MOV a1,#0 LDMDB fp,{v1-v4,fp,sp,pc} L0000dc DCB &45,&52,&52,&4f DCB &52,&21,&21,&21 DCB &20,&20,&20,&00 L0000e8 DCB &2e,&2e,&2e,&2e DCB &63,&6f,&72,&72 DCB &65,&63,&74,&00 L0000f4 DCB &31,&32,&33,&34 DCB &2f,&25,&32,&64 DCB &20,&3d,&20,&25 DCB &34,&64,&20,&25 DCB &73,&00,&00,&00 L000108 DCB &20,&3d,&20,&25 DCB &34,&64,&20,&25 DCB &73,&0a,&00,&00 AREA |C$$data|,DATA |x$dataseg| END