Escribí un código de ensamblaje simple como el siguiente:
.global _start .text _start: call _sum subq $0x8, %rsp popq %rax ret _sum: retPara obtener el valor de %rax después de la instrucción 'popq',
Ensamblé ese código usando el comando 'as' y 'ld'. y comencé el depurador de gdb poniendo un punto de interrupción en '_start'
y el resultado viene como a continuación:
B+> │0x400078 <_start> callq 0x400083 <_sum> │ │0x40007d <_start+5> sub $0x8,%rsp │ │0x400081 <_start+9> pop %rax │ │0x400082 <_start+10> retq │ │0x400083 <_sum> retqSin embargo, antes de pasar a la instrucción emergente, aparece un mensaje de error que dice que
Programa recibido señal SIGSEGV, Fallo de segmentación. No se puede acceder a la memoria en la dirección 0x1
(cuando cambié $0x8 a $0x0~$0x7, todo funcionó).
Parece que en la primera etapa, la función de suma podría ser el problema. porque literalmente no hace más que regresar.
Entonces, ¿cómo puedo modificar este código para obtener el valor de %rax después de la instrucción popq?
Gracias.
Creo que probablemente esta pregunta sea un duplicado, pero de todos modos, hay un problema en su código.
.global _start .text _start: call _sum subq $0x8, %rsp popq %rax ret # <-- return to where? _sum: ret Un main en C tiene que volver porque _start eventualmente llama a main , pero aquí, estás escribiendo _start directamente. No vuelve a ninguna parte si pones un ret .
En lugar de ret , pon esto en su lugar.
movl $60, %eax # syscall number for sys_exit movl $0, %edi # or whatever value you want your process # to return with from 0 to 255; # xor %edi, %edi is usually better if you want 0 syscallDeja un comentario si todavía falla.
Por cierto, asumí que su plataforma es Linux (debido a la sintaxis de AT&T...). Las llamadas al sistema pueden ser diferentes para una plataforma diferente.