Aquí podría ser tu PUBLICIDAD


Funciones de copia y llamada en AT & T-Assembler x86 en gcc

votos
1

Escribí el siguiente código en AT & T Assembler Syntax para 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 realidad, lo que quiero hacer es copiar el código de función de to_gen_inneren la memoria que estoy asignando con malloc, y luego saltar en él. Este código produce una falla de segmentación. 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)

De hecho, no sé por qué. Ya estoy usando lcall y lret, que he leído está pensado para llamadas absolutas, con call y ret, tampoco funcionó, el mismo error.

No sé lo que podría estar haciendo mal. ¿Alguien puede ayudarme?

Publicado el 12/03/2009 a las 19:16
fuente por usuario schoppenhauer
En otros idiomas...        العربية       

1 respuestas

votos
6

Usted tiene los siguientes problemas:

  • cuando configura la pila para su llamada a copy_bytes, quiere pushl $ to_gen_inner not pushl to_gen_inner (este último empuja el contenido de la memoria a_gen_inner points)

  • al copiar valores en el marco de pila local dentro de copy_bytes, debe escribir el registro en el que acaba de leer el parámetro, en lugar de escribir siempre EAX

  • lcall * (% eax) espera leer una dirección de la memoria apuntada por EAX, y saltar allí. Además, espera leer 48 bytes, siendo los primeros 16 el segmento. He reemplazado su lcall con llamada *% eax; también reemplazó los lrets con rets en consecuencia.

  • la llamada a printregs se ensambla como una llamada relativa, que explota ya que la instrucción que está ejecutando ya no está en el mismo desplazamiento relativo al destino que cuando se ensambló. Lo he reemplazado con

    movl $printregs, %ecx
    call *%ecx
    

(que destruye% ecx)

  • finalmente, to_gen_inner configura la pila en la entrada, pero no la destruye al salir

Con todo eso arreglado, el código se ve así:

.global main
.section .data

to_gen_inner: #x f, implicit n
        pushl %ebp
        movl %esp, %ebp
        movl $0xFF00FF00, %eax
        movl $printregs, %ecx
        call *%ecx
        movl %ebp, %esp
        popl %ebp        
        ret

.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

        call *%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
        ret

copy_bytes: #dest source length
        pushl %ebp
        movl %esp, %ebp

        subl $24, %esp

        movl 8(%ebp), %ecx # dest
        movl %ecx, -4(%ebp)

        movl 12(%ebp), %ebx # source
        movl %ebx, -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

... que se construye y corre aquí para mí. Espero que ayude.

Respondida el 12/03/2009 a las 10:39
fuente por usuario moonshadow


Aquí podría ser tu PUBLICIDAD