Ошибка сегментации сборки - PullRequest
5 голосов
/ 30 ноября 2009

Я обнаружил ошибку при запуске следующего кода сборки

#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

Обнаружена ошибка сегментации в части библиотеки C Вызов: call printf Он работает в режиме x86_64. Что-нибудь, что я пропустил во время компиляции кода x64 относительно библиотеки c? Или что-то не так с кодом

Спасибо

Ответы [ 4 ]

4 голосов
/ 30 ноября 2009

Вызывается ли инициализация библиотеки времени выполнения C? Это должно быть запущено в первую очередь для настройки stdout. Кстати, трассировка стека устранила бы сомнения относительно причины проблемы.

Кроме того, предотвратите переполнение буфера% s буфером% .12s или просто поместите байт NUL после буфера.

2 голосов
/ 07 июля 2011

Кажется, что ассемблерные вызовы для 64-битного fprintf изменены, поэтому либо свяжите 32-битную библиотеку, либо используйте следующий код:

#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 голосов
/ 30 ноября 2009

Вам нужно завершить строку, которую вы пишете в $ buffer, нулевым символом, вместо того, чтобы писать поверх одного слова три раза. Кроме того, wallyk прав: вы уверены, что CRT инициализируется?

Честно говоря, вам действительно гораздо лучше написать эту программу, которая вызывает функцию библиотеки C, на C. Записать код CPUID как встроенную сборку внутри функции __cdecl, сделать так, чтобы он записал свой результат в строковый указатель, а затем эта функция из программы на Си.

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 );

}
0 голосов
/ 30 ноября 2009

не знаком со сборкой, поэтому выстрел в темноте: обе ваши строки обнуляются?

...