moi avons écrit le code suivant dans AT & T Assembleur Syntaxe pour gcccopie et appel de fonctions dans x86 AT & T-Assembleur à gcc
.global main
.section .data
to_gen_inner: #x f, implicit n
pushl %ebp
movl %esp, %ebp
movl $0xFF00FF00, %eax
call printregs
lret
.set to_gen_inner_len, . - to_gen_inner
.section .text
main:
pushl %ebp
movl %esp, %ebp
#allocate memory
pushl $to_gen_inner_len
call malloc
popl %ecx
pushl $to_gen_inner_len
pushl to_gen_inner
pushl %eax
call copy_bytes
popl %eax
popl %ecx
popl %ecx
lcall *(%eax)
movl %ebp, %esp
popl %ebp
ret
printfregs:
.ascii "eax: %8X\nebx: %8X\necx: %8X\nedx: %8X\n\0"
printregs:
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
pushl $printfregs
call printf
popl %ecx
popl %eax
popl %ebx
popl %ecx
popl %edx
lret
copy_bytes: #dest source length
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl 8(%ebp), %ecx # dest
movl %eax, -4(%ebp)
movl 12(%ebp), %ebx # source
movl %eax, -8(%ebp)
movl 16(%ebp), %eax # length
movl %eax, -12(%ebp)
addl %eax, %ecx # last dest-byte
movl %ecx, -16(%ebp)
addl %eax, %edx # last source-byte
movl %ecx, -20(%ebp)
movl -4(%ebp), %eax
movl -8(%ebp), %ebx
movl -16(%ebp), %ecx
copy_bytes_2:
movb (%ebx), %dl
movb %dl, (%eax)
incl %eax
incl %ebx
cmp %eax, %ecx
jne copy_bytes_2
movl %ebp, %esp
popl %ebp
ret
En fait, ce que je veux faire est de copier le code de fonction de to_gen_inner
dans le mémoire que j'alloue avec malloc, puis saute dedans. Ce code produit un défaut de segmentation. gdb sais:
Program received signal SIGSEGV, Segmentation fault.
main() at speicher3.S:32
32 lcall *(%eax)
Current language: auto; currently asm
(gdb) disas $pc-5 $pc+5
Dump of assembler code from 0x80483eb to 0x80483f5:
0x080483eb <main+23>: add %al,(%eax)
0x080483ed <main+25>: pop %eax
0x080483ee <main+26>: pop %ecx
0x080483ef <main+27>: pop %ecx
0x080483f0 <main+28>: lcall *(%eax)
0x080483f2 <main+30>: mov %ebp,%esp
0x080483f4 <main+32>: pop %ebp
End of assembler dump.
(gdb) disas $pc-6 $pc+5
Dump of assembler code from 0x80483ea to 0x80483f5:
0x080483ea <main+22>: add %al,(%eax)
0x080483ec <main+24>: add %bl,0x59(%eax)
0x080483ef <main+27>: pop %ecx
0x080483f0 <main+28>: lcall *(%eax)
0x080483f2 <main+30>: mov %ebp,%esp
0x080483f4 <main+32>: pop %ebp
End of assembler dump.
(gdb)
Je ne sais pas pourquoi. J'utilise déjà lcall et lret, que j'ai lu est pensé pour les appels absolus, avec appel et ret, ça ne marche pas non plus, même erreur. Je ne sais pas ce que je pourrais faire mal. Quelqu'un peut-il m'aider s'il vous plaît?
Hm. Étrange. Votre code fonctionne aussi avec juste *% eax (ce que j'ai fait en premier). On dirait que ce n'était pas la principale raison pour laquelle mon code a échoué. En tous cas. Merci beaucoup. – schoppenhauer
Ah - on dirait que c'est call *% eax vs call * (% eax) - les premières branches à l'adresse de% eax, cette dernière appelle l'adresse contenue dans la mémoire pointée par% eax. Éditera la réponse. – moonshadow