Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.12.2010, 10:42   #1
kuraga1991
 
Регистрация: 29.12.2010
Сообщений: 3
По умолчанию Стек и bootloader

Я создал загрузчик (asm), который загружает ядро (Си) по адресу в памяти. Реальный режим. Проблема со стеком. Если параметры функции, вызываемой в ядре, передаются через регистры, все ок. Но если нет - через стек - например, переменное количество аргументов, все летит. Как инициализировать стек? Куда должны указывать регистры? Спасибо.

Вот kernel.c. В qemu код ничего не выводит, и выводит 'S', если '...' заменить на 'int x'. Отличие в передаче параметров через стек, как видно в ассемблерном коде.
Код:
__asm__(".code16gcc\n");
__asm__ ("jmp _start\n");

int extern __attribute__((noinline)) __attribute__((regparm(3))) sprintf(char * buf, const char *fmt, ...)
{
	__asm__ __volatile__ ("int 0x10" : : "a" (0x0E00 | *fmt), "b"(144));
}

void __attribute__((noreturn)) _start()
{
	char buf[128];
	sprintf(buf, "Sasha%d", 123);
	while(1);
}
Нынешняя инициализация регистров:
Код:
 	mov	ax, SETUP_ADDR>>4	; SETUP_SEG
 	mov	es, ax
 	mov	ds, ax
	mov  cs, ax
	mov  ss, ax
	mov	sp, 0x400
 	jmp	SETUP_ADDR>>4:0
Компиляция и запуск:
Код:
#!/bin/bash
gcc -c -Wall -save-temps -march=i386 -ffreestanding -Wno-main -fno-builtin -masm=intel -O0 -o kernel.o  kernel.c
ld -nostdlib -static -Ttext 0 --oformat binary -o kernel.bin kernel.o

mkdir diskc
mount -t msdos -o loop=/dev/loop3,blocksize=1024 dos.img diskc
rm diskc/BOOTOR
cp kernel.bin diskc/BOOTOR
umount diskc
rmdir diskc

nasm boot.asm -o boot.bsr
dd if=boot.bsr of=dos.img bs=512 count=1 conv=notrunc

qemu -fda dos.img -boot a
Вложения
Тип файла: zip stack_problem.zip (5.8 Кб, 13 просмотров)

Последний раз редактировалось kuraga1991; 29.12.2010 в 11:14.
kuraga1991 вне форума Ответить с цитированием
Старый 29.12.2010, 22:17   #2
kuraga1991
 
Регистрация: 29.12.2010
Сообщений: 3
По умолчанию

Я вот че понял: все правильно, он берет смещения переменных от начала какого-то сегмента... Какого? Я просто привык, что мы пишем ASSUME, а GCC такого не пишет... Или это на linux всегда так? Так вот: базирование .LC0 ведь идет по DS? А кто его устанавливает? Сейчас - я, причем абсолютно неправильно!!! А как GCC формирует сегменты? Один сегмент данных или как? Как получить его адрес, и почему он не записывается в DS? И где сегмент стека, какой из указанных опций я его отключил?

Ответьте, пожалуйста, и простите за тупые вопросы!

Вот ассемблерный код kernel.c:
Код:
	.file	"kernel.c"
	.intel_syntax noprefix
#APP
	.code16gcc

	jmp _start

#NO_APP
	.text
.globl sprintf
	.type	sprintf, @function
sprintf:
	push	ebp
	mov	ebp, esp
	push	ebx
	mov	eax, DWORD PTR [ebp+12]
	mov	al, BYTE PTR [eax]
	movsx	eax, al
	or	ah, 14
	mov	edx, 144
	mov	ebx, edx
#APP
# 6 "kernel.c" 1
	int 0x10
# 0 "" 2
#NO_APP
	pop	ebx
	leave
	ret
	.size	sprintf, .-sprintf
	.section	.rodata
.LC0:
	.string	"Sasha%d"
	.text
.globl _start
	.type	_start, @function
_start:
	push	ebp
	mov	ebp, esp
	add	esp, -128
	push	123
	push	OFFSET FLAT:.LC0
	lea	eax, [ebp-128]
	push	eax
	call	sprintf
	add	esp, 12
.L4:
	jmp	.L4
	.size	_start, .-_start
	.ident	"GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
	.section	.note.GNU-stack,"",@progbits
kuraga1991 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Стек Anabella Помощь студентам 1 20.06.2010 21:01
C++ Стек phantom4eg Помощь студентам 0 31.05.2010 01:16
Стек [ICQ] Помощь студентам 5 02.05.2010 13:44
C++ и стек MaGWaY_minsk Помощь студентам 1 14.12.2009 13:09
Стек lucky Паскаль, Turbo Pascal, PascalABC.NET 2 12.05.2009 18:35