Appel symbole externe en assembleur et
Posté le 03/12/2018 20:47
Bonjour,
Il m'a récemment pris d'essayer d'écrire un peu d'assembleur sur casio, ayant tout juste terminé de préparer ma toolchain sur mon nouvel ordi.
Du côté de la toolchain, aucun problême. GCC et as font exactement ce que je leur demande et seulement ld me pose un peu de problèmes.
En revanche, pour une raison qui m'échappe totalement, je suis parfaîtement incapable d'appeler un symbole définit dans un fichier différent de celui dans lequel je suis.
Le code exact:
-> main.s
.global _main
_main:
! load the filename address into r4
mova __filename, r0
mov r0, r4
! get openFile routine into r1
mov.l .openFile, r1
! push pr to stack
sts.l pr, @-r15
! call openFile
! bsr _useless ! don't actually execute it, but it works
jsr @r1 !triggers a System ERROR "INTERRUPT" without specifying PC, but it is here (tried infinite loops before and after)
nop
! pop pr from stack
lds.l @r15+, pr
! if r0==0, loop infinitely
cmp/eq #0, r0
1: bt 1b
nop
! return ok
rts
mov #1, r0
_useless:
rts
mov #1, r0
.align 4
.openFile:
.long _openFile
.align 4
__filename:
! "\\fls0\cal.ics\0"
! seems to be read correctly by hand, probably not the problem
.word 0x5c ! \
.word 0x5c ! \
.word 0x66 ! f
.word 0x6c ! l
.word 0x73 ! s
.word 0x30 ! 0
.word 0x5c ! \
.word 0x63 ! c
.word 0x61 ! a
.word 0x6c ! l
.word 0x2e ! .
.word 0x69 ! i
.word 0x63 ! c
.word 0x73 ! s
.word 0x00 ! \0
-> syscall_graph.s
.global _getVRAM
_getVRAM:
mov.l __syscallbase, r2
jmp @r2
mov.l __getVRAMno, r0
nop ! to preserve alignment
__getVRAMno:
.long 0x135
.global _clearVRAM
_clearVRAM:
mov.l __syscallbase, r2
jmp @r2
mov.l __clearVRAMno, r0
nop ! to preserve alignment
__clearVRAMno:
.long 0x143
.global _writeVRAM
_writeVRAM:
mov.l __syscallbase, r2
jmp @r2
mov.l __writeVRAMno, r0
nop ! to preserve alignment
__writeVRAMno:
.long 0x28
__syscallbase:
.long 0x80010070
Pour assembler ça, je fais des
sh3eb-elf-as -c <fichier.s> -o <fichier.o>
puis un linkage avec gcc pour tout ce qui aurait pu être écrit en C
sh3eb-elf-gcc -m3 -mb -O3 -nostdlib -T"build/addin.ld" build/addin.ld crt0.o lib/libfx.a main.o syscall_file.o syscall_graph.o syscall_mem.o syscall_str.o -o addin.elf -lgcc -L lib -lfx -Wall -Wextra
Les seules choses dont se plaint GCC, c'est quand il invoque ld, les redéfinitions des régions rom et ram et de .bss, et as ne me dit rien du tout.
Depuis ce matin, j'essaie d'isoler le code fautif, et ça semble être le
jsr @r1
qui crash le tout, mais le résultat est exactement le même qu'un
trapa #1
tout seul...
J'ai également essayé d'utiliser des
bsr
, mais sans succès.
L'execution de fonctions définies dans le fichier en lui même ne pose en revanche aucun problème...
J'ai aussi essayé de regarder dans les sources de gint comment le code fonctionnait pour essayer de comprendre comment réparer mon code, mais
___system_menu ne m'a pas été d'une grande aide...
Vraiment désolé de vous embêter pour quelquechose qui je suis sûr est vraiment simple...
Citer : Posté le 03/12/2018 21:00 | #
Ça c'est normal, tu as ajouté le linker script dans la liste des fichiers à linker. Il est suffisamment intelligent pour faire comme si tu avais mis -T devant, mais tu te retrouves quand même avec deux fois l'option.
sh3eb-elf-gcc -m3 -mb -O3 -nostdlib -T"build/addin.ld"
build/addin.ldcrt0.olib/libfx.amain.o syscall_file.o syscall_graph.o syscall_mem.o syscall_str.o -o addin.elf -lgcc -L lib -lfx -Wall -WextraSinon je vois que tu as mis lib/libfx.a dans la liste des fichiers également, ce n'est pas une bonne idée ; -lfx est là pour ça.
À tout hasard, est-ce que tu es sûr que ta méthode d'appel de syscall fonctionne ? Je ne sais pas si ce mov.l marche bien en delay slot (plein de choses qui devraient marcher en delay slot selon la doc ne le font pas en pratique...).
En principe ce que tu as fait est bon, et d'ailleurs c'est pas vraiment trivial !
Citer : Posté le 03/12/2018 21:22 | #
Effectivement, après avoir bougé mon mov.l avant le jmp dans l'appel de syscall, tout fonctionne parfaitement.
On n'a pas l'air d'avoir le droit de faire un mov.l dans le slot d'un jmp, mais ça n'a pas l'air de poser de problème dans celui d'un rts... Note pour plus tard, arrêter d'essayer d'utiliser les delay slots.
Et en enlevant un maximum de choses de la compilation, il me reste plus que ça:
sh3eb-elf-gcc -m3 -mb -O3 -nostdlib -T"build/addin.ld" crt0.o main.o syscall_file.o syscall_graph.o syscall_mem.o syscall_str.o -o addin.elf -lgcc -L lib -lfx -Wall -Wextra
/home/Nathan/opt/sh3eb-elf/lib/gcc/sh3eb-elf/8.2.0/../../../../sh3eb-elf/bin/ld: warning: section `.bss' type changed to PROGBITS
alors que mon linker script ne contient pas ce mot:
OUTPUT_ARCH(sh3)
ENTRY(initialize)
MEMORY
{
rom : o = 0x00300200, l = 512k
ram : o = 0x08100000, l = 64k /* pretty safe guess */
}
SECTIONS
{
.text : {
*(.pretext) /* init stuff */
*(.text)
} > rom
.rodata : {
*(.rodata)
*(.rodata.str1.4)
_romdata = . ; /* symbol for initialization data */
} > rom
.bss : {
_bbss = . ;
_bssdatasize = . ;
LONG(0); /* bssdatasize */
*(.bss) *(COMMON);
_ebss = . ;
} > ram
.data : AT(_romdata) {
_bdata = . ;
*(.data);
_edata = . ;
} > ram
}
Mais dans tous les cas, la calculatrice ne crash plus du tout
Merci beaucoup
Citer : Posté le 03/12/2018 21:40 | #
Habituellement je ne m'embête pas avec les delay slots, ou alors je teste la version safe d'abord et j'essaie ensuite. Le fait qu'un MA traîne dans le pipeline est peut-être en cause...
Une heuristique correcte pour les delays slots je pense, c'est d'exécuter uniquement des instructions qui n'utilisent pas la mémoire et n'affectent pas l'état du processeur. C'est clairement restrictif mais ça peut aider à optimiser sans prendre de risques.
Pour ton erreur de linker script, c'est normal ; c'est dû à la présence d'une variable _bssdatasize dans le crt0.s. Je pense qu'elle est là parce qu'il y a une variable similaire dans le code de base du SDK. gint s'en passe assez bien, mais tu n'es pas obligé de fouiller jusque-là. Ce n'est pas dangereux.
Bon courage pour maîtriser l'obscurité derrière l'assembleur !
Citer : Posté le 03/12/2018 22:27 | #
Merci beaucoup pour tout