Ошибка сегментации сборки
Я обнаружил ошибку во время выполнения следующего кода сборки
#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 );
}