685 lines
22 KiB
Text
685 lines
22 KiB
Text
/* ARM assembly Raspberry PI */
|
|
/* program kdtree.s */
|
|
|
|
/* REMARK 1 : this program use routines in a include file
|
|
see task Include a file language arm assembly
|
|
for the routine affichageMess conversion10
|
|
see at end of this program the instruction include */
|
|
/* REMARK 2 : In order not to use floating point numbers,
|
|
the coordinates of the points are integers numbers.
|
|
The displayed distance represents the square of the distance between 2 points */
|
|
|
|
/* This program draws heavily from the published C program. Thanks to its creator. */
|
|
|
|
/* for constantes see task include a file in arm assembly */
|
|
/************************************/
|
|
/* Constantes */
|
|
/************************************/
|
|
.include "../constantes.inc"
|
|
|
|
.equ MAXI, 3
|
|
.equ NBPOINTSRAND, 2000
|
|
.equ MAXCOORD, 10000
|
|
|
|
/***********************************************/
|
|
/* structures */
|
|
/**********************************************/
|
|
/* Définition node */
|
|
.struct 0
|
|
nodeKD_val: // value array
|
|
.struct nodeKD_val + (4 * MAXI)
|
|
nodeKD_left: // left pointer
|
|
.struct nodeKD_left + 4
|
|
nodeKD_right: // right pointer
|
|
.struct nodeKD_right + 4
|
|
nodeKD_end:
|
|
|
|
/*********************************/
|
|
/* Initialized data */
|
|
/*********************************/
|
|
.data
|
|
szMessAddressTree: .asciz "Node address : "
|
|
szMessTreeValue: .asciz " Value : "
|
|
szMessLeft: .asciz " Left : "
|
|
szMessRight: .asciz "Right : "
|
|
szMessResult: .asciz "Nearest point = "
|
|
szMessRandCoor: .asciz "\n\nRandom point coordonnés = "
|
|
szMessVisited: .asciz "Node visited = "
|
|
szMessDistance: .asciz "square distance :"
|
|
szMessStart: .asciz "Program 32 bits start.\n"
|
|
szCarriageReturn: .asciz "\n"
|
|
.align 4
|
|
tabPoint1: .int 2,3, 5,4, 9,6, 4,7, 8,1, 7,2
|
|
//tabPoint1: .int 1,7, 3,4, 4,6, 6,2, 8,12, 10,9, 12,3, 14,1
|
|
//tabPoint1: .int 3,5, 1,3, 2,8, 4,6, 5,4
|
|
.equ NBPOINTS, (. - tabPoint1) / 4
|
|
|
|
tabPoint2: .int 9,2
|
|
//tabPoint2: .int 3,7
|
|
.equ NBPOINTS2, (. - tabPoint2) / 4
|
|
iGraine: .int 123456 // random init
|
|
|
|
/*********************************/
|
|
/* UnInitialized data */
|
|
/*********************************/
|
|
.bss
|
|
stNode1: .skip nodeKD_end
|
|
KDtree1: .skip nodeKD_end * NBPOINTS
|
|
KDtree2: .skip nodeKD_end * NBPOINTS2
|
|
KdtreeRand: .skip nodeKD_end * NBPOINTSRAND
|
|
tabPointsRand: .skip nodeKD_end
|
|
sZoneConv: .skip 24 // conversion buffer
|
|
sZoneConv1: .skip 24 // conversion buffer
|
|
sBufferConv16: .skip 16
|
|
iDistance: .skip 4 // best distance
|
|
stNearest: .skip nodeKD_end // best node
|
|
nbNodeVi: .skip 4 // visited node
|
|
/*********************************/
|
|
/* code section */
|
|
/*********************************/
|
|
.text
|
|
.global main
|
|
main: @ entry of program
|
|
ldr r0,iAdrszMessStart
|
|
bl affichageMess
|
|
|
|
ldr r0,iAdrtabPoint1 @ points array address
|
|
ldr r1,iAdrKDtree1 @ KD tree address
|
|
mov r2,#NBPOINTS @ array points size
|
|
mov r3,#2 @ domension 2
|
|
bl initKDTree @ init tree
|
|
ldr r0,iAdrKDtree1 @ KD tree address
|
|
mov r1,#0 @ start index
|
|
mov r2,#NBPOINTS / 2 @ end = array points size
|
|
mov r3,#0 @ level
|
|
mov r4,#2 @ dimension 2
|
|
bl createTree
|
|
mov r8,r0 @ save median
|
|
cmp r0,#-1
|
|
beq 100f
|
|
ldr r0,iAdrKDtree1 @ KD tree address
|
|
mov r1,#2 @ dimension 2
|
|
bl displayTree
|
|
ldr r0,iAdrtabPoint2 @ points array address
|
|
ldr r1,iAdrKDtree2 @ search KDtree address
|
|
mov r2,#NBPOINTS2 @ search array points size
|
|
mov r3,#2 @ dimension 2
|
|
bl initKDTree @ init search tree
|
|
ldr r0,iAdrKDtree1 @ KDtree address
|
|
mov r1,#nodeKD_end
|
|
mla r0,r8,r1,r0 @ compute median address
|
|
ldr r1,iAdrKDtree2 @ search KDtree address
|
|
mov r2,#0 @ first index
|
|
mov r3,#2 @ dimension 2
|
|
bl searchNearest @ search nearest point
|
|
ldr r0,iAdrszMessResult @ display résult
|
|
bl affichageMess
|
|
ldr r0,iAdrstNearest @ nearest point address
|
|
ldr r0,[r0]
|
|
mov r1,#2
|
|
bl displayCoord @ coordonnés display
|
|
ldr r0,iAdrnbNodeVi @ visited nodes
|
|
ldr r0,[r0]
|
|
ldr r1,iAdrsZoneConv
|
|
bl conversion10
|
|
mov r0,#3
|
|
ldr r1,iAdrszMessVisited
|
|
ldr r2,iAdrsZoneConv
|
|
ldr r3,iAdrszCarriageReturn
|
|
bl displayStrings
|
|
ldr r0,iAdriDistance @ best distance address
|
|
ldr r0,[r0]
|
|
ldr r1,iAdrsZoneConv
|
|
bl conversion10
|
|
mov r0,#3
|
|
ldr r1,iAdrszMessDistance
|
|
ldr r2,iAdrsZoneConv
|
|
ldr r3,iAdrszCarriageReturn
|
|
bl displayStrings
|
|
|
|
bl traitRandom
|
|
|
|
100: @ standard end of the program
|
|
mov r0, #0 @ return code
|
|
mov r7, #EXIT @ request to exit program
|
|
svc #0 @ perform the system call
|
|
|
|
iAdrszCarriageReturn: .int szCarriageReturn
|
|
iAdrsZoneConv: .int sZoneConv
|
|
iAdrszMessDistance: .int szMessDistance
|
|
iAdrszMessResult: .int szMessResult
|
|
iAdrszMessVisited: .int szMessVisited
|
|
iAdrszMessStart: .int szMessStart
|
|
iAdrtabPoint1: .int tabPoint1
|
|
iAdrtabPoint2: .int tabPoint2
|
|
iAdrKDtree1: .int KDtree1
|
|
iAdrKDtree2: .int KDtree2
|
|
/***************************************************/
|
|
/* traitement random points */
|
|
/***************************************************/
|
|
traitRandom:
|
|
push {r1-r10,lr} @ save des registres
|
|
ldr r8,iAdrKdtreeRand @ KD tree address
|
|
mov r7,#nodeKD_end
|
|
ldr r10,iNbPointsRand
|
|
mov r3,#0
|
|
1: @ loop generate random coordonnes
|
|
mov r0,#MAXCOORD
|
|
bl genereraleas @ X
|
|
mov r4,r0
|
|
mov r0,#MAXCOORD
|
|
bl genereraleas @ Y
|
|
mov r5,r0
|
|
mov r0,#MAXCOORD
|
|
bl genereraleas @ Z
|
|
mov r6,r0
|
|
mla r0,r3,r7,r8
|
|
add r1,r0,#nodeKD_val @ node address
|
|
str r4,[r1] @ store X,Y,Z
|
|
str r5,[r1,#4]
|
|
str r6,[r1,#8]
|
|
mov r4,#-1 @ init pointer left and right
|
|
str r4,[r0,#nodeKD_left]
|
|
str r4,[r0,#nodeKD_right]
|
|
add r3,r3,#1
|
|
cmp r3,r10
|
|
blt 1b
|
|
|
|
mov r0,r8 @ KD tree address
|
|
mov r1,#0 @ start indice
|
|
mov r2,r10 @ array points size
|
|
mov r3,#0 @ level
|
|
mov r4,#3 @ dimension 2
|
|
bl createTree
|
|
mov r9,r0 @ save median
|
|
@ create random search point
|
|
mov r0,#MAXCOORD
|
|
bl genereraleas
|
|
mov r4,r0
|
|
mov r0,#MAXCOORD
|
|
bl genereraleas
|
|
mov r5,r0
|
|
mov r0,#MAXCOORD
|
|
bl genereraleas
|
|
mov r6,r0
|
|
ldr r3,iAdrtabPointsRand
|
|
add r0,r3,#nodeKD_val
|
|
str r4,[r0]
|
|
str r5,[r0,#4]
|
|
str r6,[r0,#8]
|
|
ldr r0,iAdrszMessRandCoor
|
|
bl affichageMess
|
|
mov r0,r3
|
|
mov r1,#3
|
|
bl displayCoord @ search
|
|
ldr r0,iAdriDistance @ init best distance address
|
|
mov r1,#0
|
|
str r1,[r0]
|
|
|
|
mla r0,r9,r7,r8 @ median KD tree address
|
|
mov r1,r3 @ search point address
|
|
mov r2,#0 @ index
|
|
mov r3,#3 @ dimension 2
|
|
bl searchNearest
|
|
ldr r0,iAdrszMessResult
|
|
bl affichageMess
|
|
ldr r0,iAdrstNearest
|
|
ldr r0,[r0]
|
|
mov r1,#3
|
|
bl displayCoord
|
|
ldr r0,iAdrnbNodeVi
|
|
ldr r0,[r0]
|
|
ldr r1,iAdrsZoneConv
|
|
bl conversion10
|
|
mov r0,#3
|
|
ldr r1,iAdrszMessVisited
|
|
ldr r2,iAdrsZoneConv
|
|
ldr r3,iAdrszCarriageReturn
|
|
bl displayStrings
|
|
ldr r0,iAdriDistance @ best distance address
|
|
ldr r0,[r0]
|
|
ldr r1,iAdrsZoneConv
|
|
bl conversion10
|
|
mov r0,#3
|
|
ldr r1,iAdrszMessDistance
|
|
ldr r2,iAdrsZoneConv
|
|
ldr r3,iAdrszCarriageReturn
|
|
bl displayStrings
|
|
100:
|
|
pop {r1-r10,pc}
|
|
iAdrKdtreeRand: .int KdtreeRand
|
|
iAdrtabPointsRand: .int tabPointsRand
|
|
iAdrszMessRandCoor: .int szMessRandCoor
|
|
iNbPointsRand: .int NBPOINTSRAND
|
|
/***************************************************/
|
|
/* init KN tree */
|
|
/***************************************************/
|
|
/* r0 array points */
|
|
/* r1 array tree address */
|
|
/* r2 points number */
|
|
/* r3 dimension */
|
|
initKDTree:
|
|
push {r1-r9,lr} @ save des registres
|
|
mov r8,#0 @ points indice
|
|
mov r4,#0 @ node tree indice
|
|
mov r6,#nodeKD_end @ structure size
|
|
1:
|
|
mla r5,r4,r6,r1 @ compute node address
|
|
mov r9,#0 @ index value
|
|
2:
|
|
ldr r7,[r0,r8,lsl #2] @ load one point coord
|
|
str r7,[r5,r9,lsl #2] @ store in node value
|
|
add r8,r8,#1 @ next point
|
|
add r9,r9,#1 @ next node value
|
|
cmp r9,r3 @ = dimension ?
|
|
blt 2b @ no loop
|
|
mov r7,#-1 @ init pointer left and right
|
|
str r7,[r5,#nodeKD_left]
|
|
str r7,[r5,#nodeKD_right]
|
|
add r4,r4,#1 @ increment node tree indice
|
|
cmp r8,r2 @ end points ?
|
|
blt 1b
|
|
100:
|
|
pop {r1-r9,pc}
|
|
/***************************************************/
|
|
/* create KD tree */
|
|
/***************************************************/
|
|
/* r0 array tree address */
|
|
/* r1 start index */
|
|
/* r2 end index
|
|
/* r3 level */
|
|
/* r4 dimention */
|
|
createTree:
|
|
push {r1-r12,lr} @ save des registres
|
|
cmp r1,r2 @ if start = end -> return -1
|
|
movge r0,#-1
|
|
bge 100f
|
|
add r5,r1,#1 @ if start + 1 = end -> return start
|
|
cmp r5,r2
|
|
moveq r0,r1
|
|
beq 100f
|
|
mov r8,r0 @ save address
|
|
mov r7,r1 @ save start index
|
|
mov r12,r2 @ save end index
|
|
mov r5,r3 @ save level
|
|
mov r10,r4 @ save dimension
|
|
mov r9,#nodeKD_end @ node structure size
|
|
mov r1,r7 @ start
|
|
mov r2,r12 @ end
|
|
bl findMedian
|
|
cmp r0,#0 @
|
|
movlt r0,#-1
|
|
blt 100f
|
|
mov r6,r0 @ save indice median
|
|
add r5,r5,#1 @ compute new value index
|
|
cmp r5,r10 @ => dimension ?
|
|
movge r5,#0
|
|
mov r0,r8 @ tree address
|
|
mov r1,r7 @ start
|
|
mov r2,r6 @ end = median
|
|
mov r3,r5 @ index
|
|
mov r4,r10 @ dimension
|
|
bl createTree
|
|
mla r1,r6,r9,r8 @ compute median address
|
|
cmp r0,#-1 @ left address is ok ?
|
|
mlane r0,r9,r0,r8 @ yes compute address
|
|
str r0,[r1,#nodeKD_left] @ and store
|
|
mov r0,r8 @ KDtree address
|
|
add r1,r6,#1 @ start = indice median + 1
|
|
mov r2,r12 @ end
|
|
mov r3,r5 @ index
|
|
mov r4,r10 @ dimension
|
|
bl createTree
|
|
mla r1,r6,r9,r8 @ compute median address
|
|
cmp r0,#-1 @ indice right ok ?
|
|
mlane r0,r9,r0,r8 @ yes compute address
|
|
str r0,[r1,#nodeKD_right] @ and store in pointer
|
|
mov r0,r6 @ return indice median node
|
|
100:
|
|
pop {r1-r12,pc}
|
|
/***************************************************/
|
|
/* find median and sort points */
|
|
/***************************************************/
|
|
/* r0 tree address */
|
|
/* r1 start tree indice
|
|
/* r2 end tree indice */
|
|
/* r3 indice */
|
|
/* r0 return median point index */
|
|
findMedian:
|
|
push {r1-r12,lr} @ save des registres
|
|
cmp r2,r1
|
|
movle r0,#-1
|
|
ble 100f
|
|
mov r7,#nodeKD_end @ node size
|
|
add r5,r1,#1 @ next node address
|
|
cmp r2,r5 @ equal to end ?
|
|
moveq r0,r1
|
|
beq 100f @ yes return
|
|
mov r8,r1 @ save start
|
|
mov r12,r0 @ save tree address
|
|
add r4,r2,r1 @ end + start
|
|
lsr r9,r4,#1 @ divide by 2 = median index
|
|
mla r10,r7,r9,r0 @ mediam md address
|
|
lsl r5,r3,#2 @ index * 4
|
|
1:
|
|
cmp r2,r8 @ end <= start
|
|
movle r0,r2 @ stop ?
|
|
ble 100f
|
|
add r6,r10,#nodeKD_val
|
|
add r11,r6,r5 @ add shift index
|
|
ldr r6,[r11] @ load pivot value
|
|
mov r0,r10 @ median address
|
|
sub r1,r2,#1 @ compute address end - 1
|
|
mul r1,r7,r1
|
|
add r1,r1,r12
|
|
bl inversion @ inversion median and end - 1
|
|
mov r11,r8 @ store=indice start
|
|
mov r4,r8 @ p =indice start
|
|
|
|
2:
|
|
cmp r4,r2 @ compare p and end
|
|
bge 5f
|
|
mla r3,r4,r7,r12 @ compute p address
|
|
add r3,r3,r5 @ add shift index
|
|
ldr r0,[r3] @ load value
|
|
cmp r0,r6 @ compare to pivot
|
|
bge 4f
|
|
cmp r4,r11 @ compare p et store
|
|
beq 3f
|
|
mla r0,r4,r7,r12 @ compute p address
|
|
mla r1,r11,r7,r12 @ compute store address
|
|
bl inversion @ inversion p and store
|
|
3:
|
|
add r11,r11,#1 @ increment store
|
|
4:
|
|
add r4,r4,#1 @ increment p
|
|
b 2b
|
|
5:
|
|
moveq r0,r9 @ equal return median index
|
|
beq 100f
|
|
mla r0,r11,r7,r12 @ store address
|
|
sub r1,r2,#1 @ end - 1
|
|
mla r1,r7,r1,r12 @ compute address
|
|
bl inversion @ inversion store and end - 1
|
|
ldr r0,[r0,#nodeKD_val] @ load store value
|
|
add r0,r0,r5 @ add shift index
|
|
ldr r1,[r10,#nodeKD_val] @ load median value
|
|
add r1,r1,r5 @ add shift index
|
|
cmp r0,r1 @ compare values
|
|
moveq r0,r9 @ equal return median index
|
|
beq 100f
|
|
cmp r11,r9 @ compare index store and median
|
|
movgt r2,r11 @ new end
|
|
movle r8,r11 @ new start
|
|
b 1b @ and loop
|
|
|
|
100:
|
|
pop {r1-r12,pc}
|
|
/***************************************************/
|
|
/* compute distance into 2 points */
|
|
/***************************************************/
|
|
/* r0 tree node address */
|
|
/* r1 search points address */
|
|
/* r2 dimension */
|
|
distance:
|
|
push {r3-r7,lr} @ save des registres
|
|
add r0,#nodeKD_val @ root node values array address
|
|
add r1,#nodeKD_val @ search node values array addresse
|
|
mov r3,#0 @ first value index
|
|
mov r7,#0 @ init distance
|
|
1:
|
|
ldr r4,[r0,r3,lsl #2] @ load value
|
|
ldr r5,[r1,r3,lsl #2] @ load value
|
|
sub r6,r5,r4 @ différence
|
|
add r3,r3,#1
|
|
mla r7,r6,r6,r7 @ compute square TODO: overflow
|
|
cmp r3,r2 @ end ?
|
|
blt 1b @ no -> loop
|
|
mov r0,r7 @ return distance
|
|
100:
|
|
pop {r3-r7,pc}
|
|
/***************************************************/
|
|
/* search nearest point */
|
|
/***************************************************/
|
|
/* r0 tree address */
|
|
/* r1 search points address */
|
|
/* r2 index */
|
|
/* r3 dimension */
|
|
searchNearest:
|
|
push {r1-r12,lr} @ save des registres
|
|
cmp r0,#-1
|
|
beq 100f
|
|
mov r7,r0 @ start with median
|
|
mov r8,r1 @ save serach point address
|
|
lsl r9,r2,#2 @ shift index
|
|
mov r10,r3 @ save dimension
|
|
mov r2,r3 @ dimension
|
|
bl distance @ compute distance
|
|
mov r11,r0
|
|
ldr r1,[r7,r9]
|
|
ldr r12,[r8,r9]
|
|
sub r12,r1
|
|
mul r6,r12,r12 @ distance axis
|
|
ldr r4,iAdriDistance
|
|
ldr r5,[r4]
|
|
cmp r5,#0 @ first distance ?
|
|
moveq r5,r11 @ new best distance
|
|
moveq r3,r7 @ new best node
|
|
beq 1f
|
|
cmp r11,r5 @ compare new distance and best distance
|
|
bgt 2f
|
|
mov r5,r11 @ new best distance
|
|
mov r3,r7 @ new best node
|
|
1:
|
|
str r5,[r4] @ store new best distance
|
|
ldr r4,iAdrstNearest @ and store best node address
|
|
str r3,[r4]
|
|
2:
|
|
ldr r1,iAdrnbNodeVi @ increment visited node
|
|
ldr r3,[r1]
|
|
add r3,r3,#1
|
|
str r3,[r1]
|
|
cmp r5,#0 @ distance = 0 -> end @
|
|
beq 100f
|
|
cmp r12,#0 @ else search in childen tree
|
|
ldrlt r0,[r7,#nodeKD_left]
|
|
ldrge r0,[r7,#nodeKD_right]
|
|
mov r1,r8
|
|
lsr r2,r9,#2
|
|
add r2,r2,#1
|
|
cmp r2,r10
|
|
movge r2,#0
|
|
mov r3,r10
|
|
bl searchNearest
|
|
ldr r4,iAdriDistance @ best distance
|
|
ldr r5,[r4]
|
|
cmp r6,r5 @ compare distance
|
|
bge 100f
|
|
cmp r12,#0 @ else search in childen tree
|
|
ldrge r0,[r7,#nodeKD_left]
|
|
ldrlt r0,[r7,#nodeKD_right]
|
|
bl searchNearest
|
|
|
|
100:
|
|
pop {r1-r12,pc}
|
|
iAdrstNearest: .int stNearest
|
|
iAdriDistance: .int iDistance
|
|
iAdrnbNodeVi: .int nbNodeVi
|
|
/***************************************************/
|
|
/* inversion */
|
|
/***************************************************/
|
|
/* r0 tree address */
|
|
/* r1 tree */
|
|
inversion:
|
|
push {r0-r4,lr} @ save des registres
|
|
add r0,#nodeKD_val
|
|
add r1,#nodeKD_val
|
|
mov r2,#0
|
|
1:
|
|
ldr r4,[r0,r2,lsl #2]
|
|
ldr r3,[r1,r2,lsl #2]
|
|
str r3,[r0,r2,lsl #2]
|
|
str r4,[r1,r2,lsl #2]
|
|
add r2,r2,#1
|
|
cmp r2,#MAXI
|
|
blt 1b
|
|
100:
|
|
pop {r0-r4,pc}
|
|
/***************************************************/
|
|
/* display tree */
|
|
/***************************************************/
|
|
/* r0 tree address */
|
|
/* r1 dimension */
|
|
displayTree:
|
|
push {r2-r12,lr} @ save des registres
|
|
mov r10,r0
|
|
mov r7,r1
|
|
mov r11,#0
|
|
mov r12,#nodeKD_end
|
|
1:
|
|
mla r9,r12,r11,r10
|
|
mov r0,r9
|
|
ldr r1,iAdrsBufferConv16
|
|
bl conversion16
|
|
mov r0,#2
|
|
ldr r1,iAdrszMessAddressTree
|
|
ldr r2,iAdrsBufferConv16
|
|
bl displayStrings
|
|
mov r8,#0
|
|
2:
|
|
add r4,r9,#nodeKD_val
|
|
ldr r0,[r4,r8,lsl #2]
|
|
ldr r1,iAdrsZoneConv
|
|
bl conversion10
|
|
mov r0,#2
|
|
ldr r1,iAdrszMessTreeValue
|
|
ldr r2,iAdrsZoneConv
|
|
bl displayStrings
|
|
add r8,r8,#1
|
|
cmp r8,r7
|
|
blt 2b
|
|
ldr r0,iAdrszCarriageReturn
|
|
bl affichageMess
|
|
|
|
add r0,r9,#nodeKD_left
|
|
ldr r0,[r0]
|
|
ldr r1,iAdrsZoneConv
|
|
bl conversion16
|
|
add r0,r9,#nodeKD_right
|
|
ldr r0,[r0]
|
|
ldr r1,iAdrsZoneConv1
|
|
bl conversion16
|
|
mov r0,#5
|
|
ldr r1,iAdrszMessLeft
|
|
ldr r2,iAdrsZoneConv
|
|
ldr r3,iAdrszMessRight
|
|
ldr r4,iAdrsZoneConv1
|
|
push {r4}
|
|
ldr r4,iAdrszCarriageReturn
|
|
push {r4}
|
|
bl displayStrings
|
|
add sp,sp,#8
|
|
add r11,r11,#1
|
|
cmp r11,#NBPOINTS / 2
|
|
blt 1b
|
|
|
|
100:
|
|
pop {r2-r12,pc}
|
|
iAdrszMessAddressTree: .int szMessAddressTree
|
|
iAdrszMessTreeValue: .int szMessTreeValue
|
|
iAdrsBufferConv16: .int sBufferConv16
|
|
iAdrszMessLeft: .int szMessLeft
|
|
iAdrszMessRight: .int szMessRight
|
|
iAdrsZoneConv1: .int sZoneConv1
|
|
/***************************************************/
|
|
/* display node coordonnées */
|
|
/***************************************************/
|
|
/* r0 node address */
|
|
/* r1 dimension */
|
|
displayCoord:
|
|
push {r1-r5,lr} @ save des registres
|
|
add r4,r0,#nodeKD_val
|
|
mov r3,r1 @ save dimension
|
|
mov r5,#0
|
|
1:
|
|
ldr r0,[r4,r5,lsl #2]
|
|
ldr r1,iAdrsZoneConv
|
|
bl conversion10
|
|
mov r0,#2
|
|
ldr r1,iAdrszMessTreeValue
|
|
ldr r2,iAdrsZoneConv
|
|
bl displayStrings
|
|
add r5,r5,#1
|
|
cmp r5,r3
|
|
blt 1b
|
|
ldr r0,iAdrszCarriageReturn
|
|
bl affichageMess
|
|
100:
|
|
pop {r1-r5,pc}
|
|
/***************************************************/
|
|
/* display multi strings */
|
|
/***************************************************/
|
|
/* r0 contains number strings address */
|
|
/* r1 address string1 */
|
|
/* r2 address string2 */
|
|
/* r3 address string3 */
|
|
/* other address on the stack */
|
|
/* thinck to add number other address * 4 to add to the stack */
|
|
displayStrings: @ INFO: displayStrings
|
|
push {r1-r4,fp,lr} @ save des registres
|
|
add fp,sp,#24 @ save paraméters address (6 registers saved * 4 bytes)
|
|
mov r4,r0 @ save strings number
|
|
cmp r4,#0 @ 0 string -> end
|
|
ble 100f
|
|
mov r0,r1 @ string 1
|
|
bl affichageMess
|
|
cmp r4,#1 @ number > 1
|
|
ble 100f
|
|
mov r0,r2
|
|
bl affichageMess
|
|
cmp r4,#2
|
|
ble 100f
|
|
mov r0,r3
|
|
bl affichageMess
|
|
cmp r4,#3
|
|
ble 100f
|
|
mov r3,#3
|
|
sub r2,r4,#4
|
|
1: @ loop extract address string on stack
|
|
ldr r0,[fp,r2,lsl #2]
|
|
bl affichageMess
|
|
subs r2,#1
|
|
bge 1b
|
|
100:
|
|
pop {r1-r4,fp,pc}
|
|
/***************************************************/
|
|
/* Generation random number */
|
|
/***************************************************/
|
|
/* r0 contains limit */
|
|
genereraleas:
|
|
push {r1-r4,lr} @ save registers
|
|
ldr r4,iAdriGraine
|
|
ldr r2,[r4]
|
|
ldr r3,iNbDep1
|
|
mul r2,r3,r2
|
|
ldr r3,iNbDep1
|
|
add r2,r2,r3
|
|
str r2,[r4] @ maj de la graine pour l appel suivant
|
|
cmp r0,#0
|
|
beq 100f
|
|
mov r1,r0 @ divisor
|
|
mov r0,r2 @ dividende
|
|
bl division
|
|
mov r0,r3 @ résult = remainder
|
|
|
|
100: @ end function
|
|
pop {r1-r4,lr} @ restaur registers
|
|
bx lr @ return
|
|
iAdriGraine: .int iGraine
|
|
iNbDep1: .int 0x343FD
|
|
iNbDep2: .int 0x269EC3
|
|
|
|
/***************************************************/
|
|
/* ROUTINES INCLUDE */
|
|
/***************************************************/
|
|
.include "../affichage.inc"
|