Ошибка сегментации сборки

Я обнаружил ошибку во время выполнения следующего кода сборки

#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 ответа

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

Также предотвратите переполнение буфера%s буфером%.12s или просто поместите NUL-байт после буфера.

Вызовы ассемблера для 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

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

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

Честно говоря, вам гораздо лучше написать эту программу, которая вызывает функцию библиотеки C, на языке C. Напишите код CPUID как встроенную сборку внутри функции __cdecl, сделайте так, чтобы он записал свой результат в строковый указатель, а затем вызовите эту функцию из 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 );

}
Другие вопросы по тегам