RosettaCodeData/Task/Rosetta-Code-Find-unimplemented-tasks/ARM-Assembly/rosetta-code-find-unimplemented-tasks.arm
2026-02-01 16:33:20 -08:00

469 lines
16 KiB
Text

/* ARM assembly Raspberry PI */
/* program tasksearchRasp.s */
/* access RosettaCode.org and data extract */
/* use openssl for access to port 443 */
/* test openssl : package libssl-dev */
/* 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 */
/*******************************************/
/* Constantes */
/*******************************************/
.include "../constantes.inc"
//.equ EXIT, 1
.equ TAILLEBUFFER, 500
.equ SSL_OP_NO_SSLv3, 0x02000000
.equ SSL_OP_NO_COMPRESSION, 0x00020000
.equ SSL_MODE_AUTO_RETRY, 0x00000004
.equ SSL_CTRL_MODE, 33
.equ BIO_C_SET_CONNECT, 100
.equ BIO_C_DO_STATE_MACHINE, 101
.equ BIO_C_SET_SSL, 109
.equ BIO_C_GET_SSL, 110
.equ LGBUFFERREQ, 512001
.equ LGBUFFER2, 128001
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessDebutPgm: .asciz "Program 32 bits start \n"
szRetourLigne: .asciz "\n"
szMessFinOK: .asciz "Program end OK. \n"
szMessErreur: .asciz "Erreur !!!"
//szMessExtractArea: .asciz "Extraction = "
szMessConnectOK: .asciz "Connexion site OK.\n"
szMessInitOK: .asciz "Initialisation SSL OK.\n"
szMessReqOK: .asciz "Send requete OK.\n"
szNomSite1: .asciz "www.rosettacode.org:443" @ host name and port
szLibStart: .asciz "<query><categorymembers>" @ search string
szLibsearch1: .asciz "<cm pageid="
szLibsearch2: .asciz "title="
szNomrepCertif: .asciz "/pi/certificats"
szRequete1: .asciz "GET /w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=1000&format=xml HTTP/1.1 \r\nHost: rosettacode.org\r\nConnection: keep-alive\r\nContent-Type: text/plain\r\n\r\n"
szRequete2: .asciz "GET /w/api.php?action=query&list=categorymembers&cmtitle=Category:ARM%20Assembly&cmlimit=500&format=xml HTTP/1.1 \r\nHost: rosettacode.org\r\nConnection: keep-alive\r\nContent-Type: text/plain\r\n\r\n"
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
.align 4
sBufferreq: .skip LGBUFFERREQ
sBufferreq1: .skip LGBUFFERREQ
szExtractArea: .skip TAILLEBUFFER
szExtractArea1: .skip TAILLEBUFFER
szTaskName: .skip 128
szTaskNamePgm: .skip 128
.align 4
stNewSSL: .skip 200
/*********************************/
/* code section */
/*********************************/
.text
.global main
main:
ldr r0,iAdrszMessDebutPgm
bl affichageMess @ start message
/* connexion host port 443 and send query */
ldr r0,iAdrszNomSite1
ldr r1,iAdrszRequete1
ldr r2,iAdrsBufferreq
bl envoiRequete
cmp r0,#-1
beq 99f @ error ?
ldr r0,iAdrszNomSite1
ldr r1,iAdrszRequete2
ldr r2,iAdrsBufferreq1
bl envoiRequete
cmp r0,#-1
beq 99f @ error ?
bl analyseReponse
ldr r0,iAdrszMessFinOK @ end message
bl affichageMess
mov r0, #0 @ return code ok
b 100f
99:
ldr r0,iAdrszMessErreur @ error
bl affichageMess
mov r0, #1 @ return code error
b 100f
100:
mov r7,#EXIT @ program end
svc #0 @ system call
iAdrszMessDebutPgm: .int szMessDebutPgm
iAdrszMessFinOK: .int szMessFinOK
iAdrszMessErreur: .int szMessErreur
iAdrszNomSite1: .int szNomSite1
iAdrszRequete2: .int szRequete2
iAdrszRequete1: .int szRequete1
iAdrsBufferreq: .int sBufferreq
iAdrsBufferreq1: .int sBufferreq1
/*********************************************************/
/* connexion host port 443 and send query */
/*********************************************************/
envoiRequete:
push {r2-r9,lr} @ save registers
mov r8,r0 @ save address site name
mov r9,r1 @ save address requete
mov r7,r2 @ save address buffer
@*************************************
@ openSsl functions use *
@*************************************
@init ssl
mov r0,#0
bl OPENSSL_init_crypto
bl ERR_load_BIO_strings
mov r2, #0
mov r1, #0
mov r0, #2
bl OPENSSL_init_crypto
mov r2, #0
mov r1, #0
mov r0, #0
bl OPENSSL_init_ssl
cmp r0,#0
blt erreur
bl TLS_client_method
bl SSL_CTX_new
cmp r0,#0
ble erreur
mov r6,r0 @ save ctx
ldr r1,iFlag
bl SSL_CTX_set_options
mov r0,r6
mov r1,#0
ldr r2,iAdrszNomrepCertif
bl SSL_CTX_load_verify_locations
cmp r0,#0
ble erreur
mov r0,r6
bl BIO_new_ssl_connect
cmp r0,#0
beq erreur
cmp r0,#-1
beq erreur
mov r5,r0 @ save bio
ldr r0,iAdrszMessInitOK
bl affichageMess
mov r0,r5
mov r1,#BIO_C_GET_SSL
mov r2,#0
ldr r3,iAdrstNewSSL
bl BIO_ctrl
ldr r0,iAdrstNewSSL
ldr r0,[r0]
mov r1,#SSL_CTRL_MODE
mov r2,#SSL_MODE_AUTO_RETRY
mov r3,#0
bl SSL_ctrl
mov r0,r5 @ bio
mov r1,#BIO_C_SET_CONNECT
mov r2,#0
mov r3,r8 @ site address
bl BIO_ctrl
mov r0,r5 @ bio
mov r1,#BIO_C_DO_STATE_MACHINE
mov r2,#0
mov r3,#0
bl BIO_ctrl
cmp r0,#0
blt erreur
ldr r0,iAdrszMessConnectOK
bl affichageMess
@ compute query length
mov r2,#0 @ init length
mov r1,r9 @ query address
1: @ loop compute length query
ldrb r0,[r1,r2]
cmp r0,#0
addne r2,#1
bne 1b
@ send query
mov r0,r5 @ bio
@ r1 = address query
@ r2 = length query
mov r3,#0
bl BIO_write @ send query
cmp r0,#0
blt erreur
ldr r0,iAdrszMessReqOK
bl affichageMess
2: @ begin loop to read datas
mov r0,r5 @ bio
mov r1,r7 @ buffer address
mov r2,#LGBUFFERREQ - 1
mov r3,#0
bl BIO_read
cmp r0,#0
ble 4f @ error ou pb server
mov r1,r7
add r7,r0
sub r2,r7,#6
ldr r2,[r2]
ldr r3,iCharEnd
cmp r2,r3 @ text end ?
beq 4f
mov r1,#0xFF @ delay loop
3:
subs r1,#1
bgt 3b
b 2b @ loop read other chunk
4: @ read end
//ldr r0,iAdrsBufferreq @ to display buffer response of the query
//bl affichageMess
mov r0, r5 @ close bio
bl BIO_free_all
mov r0,#0
b 100f
erreur: @ error display
ldr r1,iAdrszMessErreur
bl afficheerreur
mov r0,#-1 @ error code
b 100f
100:
pop {r2-r9,pc} @ restaur registers
iFlag: .int SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION
iAdrstNewSSL: .int stNewSSL
iAdrszNomrepCertif: .int szNomrepCertif
iCharEnd: .int 0x0A0D300A
iAdrszMessConnectOK: .int szMessConnectOK
iAdrszMessInitOK: .int szMessInitOK
iAdrszMessReqOK: .int szMessReqOK
/*********************************************************/
/* response analyze */
/*********************************************************/
analyseReponse:
push {r1-r6,lr} @ save registers
@ search start in task buffer
ldr r0,iAdrsBufferreq @ buffer address
mov r7,r0
ldr r1,iAdrszLibStart @ key text address
bl rechercheSousChaine
cmp r0,#-1
beq 99f
add r7,r7,r0 @ new search buffer address
mov r0,r7
@ search start in task buffer
ldr r0,iAdrsBufferreq11 @ buffer address
mov r5,r0
ldr r1,iAdrszLibStart @ key text address
bl rechercheSousChaine
cmp r0,#-1
beq 99f @ error ?
add r5,r5,r0
mov r0,r5
1: @ loop begin to find task in program buffer
mov r0,r5
ldr r1,iAdrszLibsearch1 @ text code task address
mov r2,#1 @ occurence key text
mov r3,#2 @ offset
ldr r4,iAdrszExtractArea1 @ address result area
bl extChaine
cmp r0,#-1
beq 99f @ error ?
mov r5,r0 @ new address to search
ldr r0,iAdrszExtractArea1
bl conversionAtoD @ conversion code task to numeric
mov r10,r0 @ save numeric code
mov r0,r5 @ search task name in pgm buffer @
ldr r1,iAdrszLibsearch2 @ key text address
mov r2,#1 @ occurence key text
mov r3,#2 @ offset
ldr r4,iAdrszTaskNamePgm @ address result area
bl extChaine
cmp r0,#-1
beq 99f
mov r5,r0 @ new address to search
2: @ loop search buffer tasks
mov r0,r7
ldr r1,iAdrszLibsearch1 @ key text address
mov r2,#1 @ occurence key text
mov r3,#2 @ offset
ldr r4,iAdrszExtractArea @ address result area
bl extChaine
cmp r0,#-1
beq 99f
mov r7,r0
mov r0,r7
ldr r1,iAdrszLibsearch2 @ key text address
mov r2,#1 @ occurence key text
mov r3,#2 @ offset
ldr r4,iAdrszTaskName @ address result area
bl extChaine
cmp r0,#-1
beq 99f
mov r7,r0 @ new search address in task buffer
ldr r0,iAdrszExtractArea
bl conversionAtoD @ conversion code task in numeric
cmp r10,r0 @ compere two task code
beq 10f @ search next codes if equals
ldr r0,iAdrszTaskName @ else display task name
bl affichageMess
ldr r0,iAdrszRetourLigne
bl affichageMess
add r0,r7,#4 @ search if end of task list
ldrb r2,[r0]
cmp r2,#'/'
bne 2b @ no -> loop
add r0,#1
ldrb r2,[r0]
cmp r2,#'c'
bne 2b @ no -> loop
b 100f @ yes -> list end
10:
add r0,r5,#4 @ search if end of pgm task list
ldrb r2,[r0]
cmp r2,#'/'
bne 1b
add r0,#1
ldrb r2,[r0]
cmp r2,#'c'
bne 1b
b 100f @ list pgm end
99:
ldr r0,iAdrszMessErreur1 @ error
bl affichageMess
mov r0, #-1 @ error return code
b 100f
100:
pop {r1-r6,pc} @ restaur registers
iAdrsBufferreq11: .int sBufferreq1
iAdrszLibStart: .int szLibStart
iAdrszLibsearch1: .int szLibsearch1
iAdrszLibsearch2: .int szLibsearch2
iAdrszTaskName: .int szTaskName
iAdrszTaskNamePgm: .int szTaskNamePgm
iAdrszExtractArea: .int szExtractArea
iAdrszExtractArea1: .int szExtractArea1
iAdrszRetourLigne: .int szRetourLigne
iAdrszMessErreur1: .int szMessErreur
/*********************************************************/
/* Text Extraction behind text key */
/*********************************************************/
/* r0 buffer address */
/* r1 key text to search */
/* r2 number occurences to key text */
/* r3 offset */
/* r4 result address */
extChaine:
push {r2-r8,lr} @ save registers
mov r5,r0 @ save buffer address
mov r6,r1 @ save key text
@ compute text length
mov r7,#0
1: @ loop
ldrb r0,[r5,r7] @ load a byte
cmp r0,#0 @ end ?
addne r7,#1 @ no -> loop
bne 1b
add r7,r5 @ compute text end
mov r8,#0
2: @ compute length text key
ldrb r0,[r6,r8]
cmp r0,#0
addne r8,#1
bne 2b
3: @ loop to search nième(r2) key text
mov r0,r5
mov r1,r6
bl rechercheSousChaine
cmp r0,#0
blt 100f
subs r2,#1
addgt r5,r0
addgt r5,r8
bgt 3b
add r0,r5 @ add address text to index
add r3,r0 @ add offset
sub r3,#1
@ and add length key text
add r3,r8
cmp r3,r7 @ > at text end
movge r0,#-1 @ yes -> error
bge 100f
mov r0,#0
4: @ character loop copy
ldrb r2,[r3,r0]
strb r2,[r4,r0]
cmp r2,#0 @ text end ?
moveq r0,#0 @ return zero
beq 100f
cmp r2,#'"' @ text end ?
beq 5f
cmp r0,#48 @ extraction length
beq 5f
add r0,#1
b 4b @ and loop
5:
mov r2,#0 @ store final zéro
strb r2,[r4,r0]
add r0,#1
add r0,r3 @ r0 return the last position of extraction
@ it is possible o search another text
100:
pop {r2-r8,pc} @ restaur registers
/******************************************************************/
/* search substring in string */
/******************************************************************/
/* r0 contains address string */
/* r1 contains address substring */
/* r0 return start index substring or -1 if not find */
rechercheSousChaine:
push {r1-r6,lr} @ save registers
mov r2,#0 @ index position string
mov r3,#0 @ index position substring
mov r6,#-1 @ search index
ldrb r4,[r1,r3] @ load first byte substring
cmp r4,#0 @ zero final ?
moveq r0,#-1 @ error
beq 100f
1:
ldrb r5,[r0,r2] @ load string byte
cmp r5,#0 @ zero final ?
moveq r0,#-1 @ yes -> not find
beq 100f
cmp r5,r4 @ compare character two strings
beq 2f
mov r6,#-1 @ not equal - > raz index
mov r3,#0 @ and raz byte counter
ldrb r4,[r1,r3] @ and load byte
add r2,#1 @ and increment byte counter
b 1b @ and loop
2: @ characters equal
cmp r6,#-1 @ first character equal ?
moveq r6,r2 @ yes -> start index in r6
add r3,#1 @ increment substring counter
ldrb r4,[r1,r3] @ and load next byte
cmp r4,#0 @ zero final ?
beq 3f @ yes -> search end
add r2,#1 @ else increment string index
b 1b @ and loop
3:
mov r0,r6 @ return start index substring in the string
100:
pop {r1-r6,pc} @ restaur registres
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"