/* ARM assembly Raspberry PI */ /* program fcttime.s */ /* Constantes */ .equ STDOUT, 1 @ Linux output console .equ EXIT, 1 @ Linux syscall .equ WRITE, 4 @ Linux syscall .equ N1, 1000000 @ loop number .equ NBMEASURE, 10 @ measure number /*********************************/ /* Initialized data */ /*********************************/ .data szMessError: .asciz "Error detected !!!!. \n" szMessSep: .asciz "****************************\n" szMessTemps: .ascii "Function time : " sSecondes: .fill 10,1,' ' .ascii " s " sMicroS: .fill 10,1,' ' .asciz " micros\n" szCarriageReturn: .asciz "\n" /*********************************/ /* UnInitialized data */ /*********************************/ .bss .align 4 dwDebut: .skip 8 dwFin: .skip 8 /*********************************/ /* code section */ /*********************************/ .text .global main main: @ entry of program adr r0,mult @ function address to measure mov r1,#1 @ parameter 1 function mov r2,#2 @ parameter 2 function bl timeMesure cmp r0,#0 blt 99f adr r0,sum @ function address to measure mov r1,#1 mov r2,#2 bl timeMesure cmp r0,#0 blt 99f b 100f 99: @ error ldr r0,iAdrszMessError bl affichageMess 100: @ standard end of the program mov r0, #0 @ return code mov r7, #EXIT @ request to exit program svc #0 @ perform the system call iAdrszMessError: .int szMessError iAdrszCarriageReturn: .int szCarriageReturn /**************************************************************/ /* examble function sum */ /**************************************************************/ /* r0 contains op 1 */ /* r1 contains op 2 */ sum: push {lr} @ save registres add r0,r1 100: pop {lr} @ restaur registers bx lr @ function return /**************************************************************/ /* exemple execution multiplication */ /**************************************************************/ /* r0 contains op 1 */ /* r1 contains op 2 */ mult: push {lr} @ save registres mul r0,r1,r0 100: pop {lr} @ restaur registers bx lr @ function return /**************************************************************/ /* Procedure for measuring the execution time of a routine */ /**************************************************************/ /* r0 contains the function address */ timeMesure: push {r1-r8,lr} @ save registres mov r4,r0 @ save function address mov r5,r1 @ save param 1 mov r6,r2 @ save param 2 mov r8,#0 1: ldr r0,iAdrdwDebut @ start time area mov r1,#0 mov r7, #0x4e @ call system gettimeofday svc #0 cmp r0,#0 @ error ? blt 100f @ return error ldr r7,iMax @ run number mov r0,r5 @ param function 1 mov r1,r6 @ param function 2 2: @ loop blx r4 @ call of the function to be measured subs r7,#1 @ decrement run bge 2b @ loop if not zero @ ldr r0,iAdrdwFin @ end time area mov r1,#0 mov r7, #0x4e @ call system gettimeofday svc #0 cmp r0,#0 @ error ? blt 100f @ return error @ compute time ldr r0,iAdrdwDebut @ start time area //vidmemtit mesure r0 2 ldr r2,[r0] @ secondes ldr r3,[r0,#4] @ micro secondes ldr r0,iAdrdwFin @ end time area ldr r1,[r0] @ secondes ldr r0,[r0,#4] @ micro secondes sub r2,r1,r2 @ secondes number subs r3,r0,r3 @ microsecondes number sublt r2,#1 @ if negative sub 1 seconde to secondes ldr r1,iSecMicro addlt r3,r1 @ and add 1000000 to microsecondes number mov r0,r2 @ conversion secondes ldr r1,iAdrsSecondes bl conversion10 mov r0,r3 @ conversion microsecondes ldr r1,iAdrsMicroS bl conversion10 ldr r0,iAdrszMessTemps bl affichageMess @ display message add r8,#1 cmp r8,#NBMEASURE ble 1b ldr r0,iAdrszMessSep @ display separator bl affichageMess 100: pop {r1-r8,lr} @ restaur registers bx lr @ function return iMax: .int N1 iAdrdwDebut: .int dwDebut iAdrdwFin: .int dwFin iSecMicro: .int 1000000 iAdrsSecondes: .int sSecondes iAdrsMicroS: .int sMicroS iAdrszMessTemps: .int szMessTemps iAdrszMessSep: .int szMessSep /******************************************************************/ /* display text with size calculation */ /******************************************************************/ /* r0 contains the address of the message */ affichageMess: push {r0,r1,r2,r7,lr} @ save registres mov r2,#0 @ counter length 1: @ loop length calculation ldrb r1,[r0,r2] @ read octet start position + index cmp r1,#0 @ if 0 its over addne r2,r2,#1 @ else add 1 in the length bne 1b @ and loop @ so here r2 contains the length of the message mov r1,r0 @ address message in r1 mov r0,#STDOUT @ code to write to the standard output Linux mov r7, #WRITE @ code call system "write" svc #0 @ call systeme pop {r0,r1,r2,r7,lr} @ restaur registers */ bx lr @ return /******************************************************************/ /* Converting a register to a decimal */ /******************************************************************/ /* r0 contains value and r1 address area */ .equ LGZONECAL, 10 conversion10: push {r1-r4,lr} @ save registers mov r3,r1 mov r2,#LGZONECAL 1: @ start loop bl divisionpar10 @ r0 <- dividende. quotient ->r0 reste -> r1 add r1,#48 @ digit strb r1,[r3,r2] @ store digit on area cmp r0,#0 @ stop if quotient = 0 subne r2,#1 @ previous position bne 1b @ else loop @ end replaces digit in front of area mov r4,#0 2: ldrb r1,[r3,r2] strb r1,[r3,r4] @ store in area begin add r4,#1 add r2,#1 @ previous position cmp r2,#LGZONECAL @ end ble 2b @ loop mov r1,#' ' 3: strb r1,[r3,r4] add r4,#1 cmp r4,#LGZONECAL @ end ble 3b 100: pop {r1-r4,lr} @ restaur registres bx lr @return /***************************************************/ /* division par 10 signé */ /* Thanks to http://thinkingeek.com/arm-assembler-raspberry-pi/* /* and http://www.hackersdelight.org/ */ /***************************************************/ /* r0 dividende */ /* r0 quotient */ /* r1 remainder */ divisionpar10: /* r0 contains the argument to be divided by 10 */ push {r2-r4} @ save registers */ mov r4,r0 mov r3,#0x6667 @ r3 <- magic_number lower movt r3,#0x6666 @ r3 <- magic_number upper smull r1, r2, r3, r0 @ r1 <- Lower32Bits(r1*r0). r2 <- Upper32Bits(r1*r0) mov r2, r2, ASR #2 @ r2 <- r2 >> 2 mov r1, r0, LSR #31 @ r1 <- r0 >> 31 add r0, r2, r1 @ r0 <- r2 + r1 add r2,r0,r0, lsl #2 @ r2 <- r0 * 5 sub r1,r4,r2, lsl #1 @ r1 <- r4 - (r2 * 2) = r4 - (r0 * 10) pop {r2-r4} bx lr @ return