2009-11-30 23 views
5

me ha detectado un error durante la ejecución del siguiente códigoAsamblea Segmentación de fallos

Asamblea
#cpuid using C library Functions 
.section .data 
output: 
.asciz "The Processor Vendor ID is '%s'\n" 
.section .bss 
.lcomm buffer, 12 
.section .text 
.globl main 
main: 
movq $0, %rax 
cpuid 
movq $buffer, %rdi 
movq %rbx, (%rdi) 
movq %rdx, (%rdi) 
movq %rcx, (%rdi) 
pushq $buffer 
pushq $output 
call printf 
addq $8, %rsp 
pushq $0 
call exit 

Se encontró fallo de segmentación en la parte de la biblioteca C de llamada: llamada printf Se ejecuta en modo x86_64. ¿Algo que perdí durante la compilación del código x64 con respecto a la biblioteca c? O hay algo mal con el código

Gracias

+2

posible que desee aumentar% RDI por una cantidad apropiada entre de esos movq – Managu

+1

Gracias todos, resolví el problema. Fue la lib mal que he cargado funciona bien después de que LD manualmente con /lib/ld-linux-x86-64.so.2 y sustituye la función principal con _start. I ld como enlace dinámico. Lo siento por la mala –

Respuesta

0
no

familiarizado con el montaje, por lo que un disparo en la oscuridad: son a la vez sus cuerdas terminada en nulo? Se está llamando

+0

Inglés '.asciz' añade automáticamente el terminador nulo. – querist

4

inicialización de la biblioteca de ejecución C? Eso debe ejecutarse primero para que se pueda configurar el stdout. Por cierto, un rastro de pila eliminaría la duda sobre la causa del problema.

También, evitar la conversión del% s se desborde el buffer con .12s%, o simplemente poner un byte NUL después de búfer.

0

Necesitas nulo terminar la serie se escribe en el buffer $, en lugar de escribir una encima de la palabra tres veces. Además, Wallyk tiene razón: ¿estás seguro de que el CRT se está inicializando?

Honestamente, realmente está mucho mejor escribiendo este programa, que llama a una función de biblioteca C, en C. Escriba el código CPUID como ensamblado en línea dentro de una función __cdecl, haga que escriba su resultado en un puntero de cadena, y luego llamar a esa función desde un programa C.

void GetCPUID(char *toStr) 
{ 
// inline assembly left as exercise for the reader.. 
// write ebx to *toStr, ecx to *toStr+4, edx to *toStr+8, and 0 to *toStr+12 
} 

void PrintCPUID() 
{ 
    char cpuidstr[16]; 
    GetCPUID(cpuidstr); 
    printf("cpuid: %s\n", cpuidstr); 

} 
2

Las llamadas ensamblador para fprintf 64 bits son aparentemente cambiaron, así que o enlazar la librería 32 o utilice el siguiente código:

#cpuid using C library Functions 
.section .data 
output: 
.asciz "The Processor Vendor ID is '%s'\n" 
.section .bss 
.lcomm buffer, 12 
.section .text 
.globl main 
main: 
movq $0, %rax 
cpuid 
movq $buffer, %rdi 
movq %rbx, (%rdi) 
movq %rdx, 4(%rdi) 
movq %rcx, 8(%rdi) 
movq $buffer, %rsi #1st parameter 
movq $output, %rdi #2nd parameter 
movq $0, %rax 
call printf 
addq $8, %rsp 
pushq $0 
call exit 
+0

sus instrucciones movq no incrementan '(% RDI)', así que a menos que me falta algo, '$ búfer movq, (% RDI)' es simplemente va a ser sobrescrito por el '$ movq de salida, unos cuantos% rdi' líneas más tarde. Puedo ver lo que estás haciendo, pero ¿por qué usar '% rdi' cuando simplemente vas a copiar' $ buffer' a '% rsi' algunas líneas más tarde de todos modos? – querist