Написал функцию для отладочного вывода числа на экран в своей ОС: Код (Text): void dbg_print_number(size_t number, char base, char digit_count) { char buffer[64 + 1]; buffer[sizeof(buffer) - 1] = 0; char i = sizeof(buffer) - 2; do { buffer[i] = digits[number % base]; i--; if (digit_count) digit_count--; number = number / base; } while (number); for (; digit_count; digit_count--) { buffer[i] = '0'; i--; } dbg_print_string(&buffer[i + 1]); } Но GCC почему то добавляет весьма странный код в начало этой функции: Разумеется, он не работает корректно и рушит систему. Что это такое и как от этой ерунды избавится?
Ты бы хоть первую цифру версии gcc озвучил бы. Лучше парочку. У меня 4.4.5, он делает так: Код (Text): dbg_print_number: .LFB0: .cfi_startproc pushq %rbp # .cfi_def_cfa_offset 16 movq %rsp, %rbp #, .cfi_offset 6, -16 .cfi_def_cfa_register 6 pushq %rbx # subq $120, %rsp #, movq %rdi, -104(%rbp) # number, number movl %esi, %ecx # base, tmp67 movl %edx, %eax # digit_count, tmp68 movb %cl, -108(%rbp) # tmp67, base movb %al, -112(%rbp) # tmp68, digit_count movb $0, -32(%rbp) #, buffer movb $63, -17(%rbp) #, i .L3: movsbl -17(%rbp),%ecx # i, D.2130 Как видим ничего не пытается писать по адресу 0x28. Но как бы там ни было, попробуй при компиляции использовать во-первых, -Wall, во-вторых -O2. Первое поможет тебе код чище писать, второе заставит gcc иначе подходить к генерации процессорного кода.
-O2 не помогает - так инструкция всё равно присутствует. Код (Text): $ gcc --version gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 У меня такое ощущение, что я не все стандартные библиотеки обрубил и он ещё пытается использовать какие-то структуры данных ОС. Вот флаги компиляции: Код (Text): CFLAGS = -ffreestanding -m64 -mcmodel=kernel Может ещё какую-нибудь опцию забыл?
С твоими флагами компиляции мне всё равно не удаётся получить обращение к gs:0x28. Попробовал ещё gcc-4.3.4 тоже не вышло. AFAIK, gcc по-любому будет линковать с libgcc.a. Или её надо вручную указывать... Не знаю, честно говоря, с этими вопросами я лишь понаслышке знаком. Вообще, я краем уха слышал, что fs и gs используются в лине для организации TLS. Ты там с __thread ничего не мутил?
А вот это помогло. Заодно смог убрать пустую __stack_chk_fail, которую пришлось объявить, чтобы не было ошибки линковки. А теперь мне уже просто интересно, что всё это было и как это работает.
Видать убунта втыкает stack-protector по-умолчанию. То ли в spec файлах, то ли ещё как. KIV Не знаю будет ли это достаточным ответом, но всё же, вот цитата из info gcc: Код (Text): `-fstack-protector' Emit extra code to check for buffer overflows, such as stack smashing attacks. This is done by adding a guard variable to functions with vulnerable objects. This includes functions that call alloca, and functions with buffers larger than 8 bytes. The guards are initialized when a function is entered and then checked when the function exits. If a guard check fails, an error message is printed and the program exits.