2009-11-30 15 views
5

I a rencontré une erreur lors de l'exécution du Code Assemblée suivanteAssemblée Segmentation Fault

#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 

Il a rencontré une erreur de segmentation dans la partie de la bibliothèque C Appel: appel printf Il est en cours d'exécution en mode x86_64. Tout ce que j'ai manqué lors de la compilation du code x64 en ce qui concerne la bibliothèque c? Ou est-il quelque chose de mal avec le code

Merci

+2

pourrait vouloir augmenter% rdi par une quantité appropriée entre – Managu

+1

Merci de ces movq tout le monde, j'ai résolu le problème. C'était la mauvaise lib que j'ai chargée fonctionne bien après l'avoir ld manuellement avec /lib/ld-linux-x86-64.so.2 et j'ai remplacé la fonction principale par _start. Je l'ai mis en lien dynamique. Désolé pour le mauvais anglais –

Répondre

0

pas familier avec l'assemblage, donc un coup de feu dans l'obscurité: les deux sont vos chaînes NULL résilié?

+0

'.asciz' ajoute automatiquement la terminaison nulle. – querist

4

L'initialisation de la bibliothèque C runtime est-elle appelée? Cela doit fonctionner en premier pour que stdout soit mis en place. BTW, une trace de la pile permettrait d'éliminer le doute quant à la cause du problème.

De même, empêchez la conversion de% s de déborder du tampon avec% .12s, ou mettez simplement un octet NUL après le tampon.

0

Vous devez mettre à zéro la chaîne que vous écrivez dans $ buffer, plutôt que d'écrire trois fois au-dessus d'un mot. En outre, wallyk a raison: êtes-vous sûr que le CRT est en cours d'initialisation? Honnêtement, vous êtes vraiment beaucoup mieux d'écrire ce programme, qui appelle une fonction de bibliothèque C, en C. Écrivez le code CPUID en tant qu'assemblage en ligne dans une fonction __cdecl, écrivez son résultat à un pointeur de chaîne, puis appelez cette fonction depuis un programme 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

Les appels en assembleur pour fprintf 64bit sont apparemment changé, donc soit lier la bibliothèque 32bit ou utilisez le code suivant:

#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

vos instructions movq n'incrémentent pas '(% rdi)', donc à moins que je ne manque quelque chose, 'movq $ buffer, (% rdi)' va simplement être écrasé par votre 'movq $ output,% rdi' lignes plus tard. Je peux voir ce que vous faites, mais pourquoi utiliser '% rdi' quand vous allez simplement copier' $ buffer' sur '% rsi' quelques lignes plus tard? – querist

Questions connexes