[英]C function doesn't return after using __asm__ command
我正在嘗試使用指南https://github.com/cfenollosa/os-tutorial從頭開始構建操作系統。 我已經調試了到目前為止所做的項目(第 16 章),當我嘗試運行它時遇到一個問題,我發現 ip 在調用void port_byte_out(unsigned short port, unsigned char data)
。
unsigned char port_byte_in(unsigned short port);
void port_byte_out(unsigned short port, unsigned char data);
unsigned short port_word_in(unsigned short port);
void port_word_out(unsigned short port, unsigned short data);
unsigned char result;
__asm__ ( " in %%dx , %%al " : "=a" ( result ) : "d" ( port ));
return result ;
}
void port_byte_out ( unsigned short port , unsigned char data ) {
__asm__ ( "out %%al , %%dx " : : "a" ( data ) , "d" ( port ));
}
unsigned short port_word_in ( unsigned short port ) {
unsigned short result ;
__asm__ ( " in %%dx , %%ax " : "=a" ( result ) : "d" ( port ));
return result;
}
void port_word_out ( unsigned short port , unsigned short data ) {
__asm__ ( " out %%ax , %%dx " : : "a" ( data ) , "d" ( port ));
}
set_cursor_offset(int)
- 調用者代碼 functionvoid set_cursor_offset(int offset) {
offset /= 2;
port_byte_out(REG_SCREEN_CTRL, 14);
port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset >> 8));
port_byte_out(REG_SCREEN_CTRL, 15);
port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset & 0xff));
}
# $@ = target file
# $< = first dependcy
# $^ = all dependecies
C_SOURCES = $(wildcard kernel/*.c drivers/*.c)
HEADERS = $(wildcard kernel/*.h drivers/*.h)
OBJ = ${C_SOURCES:.c=.o}
CC = /usr/local/cross/bin/i686-elf-gcc
LD = /usr/local/cross/bin/i686-elf-ld
GDB = gdb
CFLAGS = -g
image.bin: boot_sector.bin kernel.bin
cat $^ > $@
kernel.bin: boot/kernel_entry.o ${OBJ}
${LD} -o $@ -Ttext 0x1000 $^ --oformat binary
kernel.elf: boot/kernel_entry.o ${OBJ}
${LD} -g -o $@ -Ttext 0x1000 $^
run: image.bin
qemu-system-x86_64 -fda $<
debug: image.bin kernel.elf
qemu-system-x86_64 -s -fda image.bin &
${GDB} -ex "target remote localhost:1234" -ex "symbol-file kernel.elf"
%.o: */%.c ${HEADERS}
${CC} ${FLAGS} -ffreestanding -c $< -o $@
%.o: %.asm
nasm $< -f elf -o $@
%.bin: */%.asm
nasm $< -f bin -o $@
clean:
rm -rf *.bin *.dis *.o *.elf
rm kernel/*.bin kernel/*.o boot/*.bin boot/*.o
rm drivers/*.bin drivers/*.o
rm image.bin
.
├── bin
├── boot
│ ├── 32bit-gdt.asm --> gdt table
│ ├── boot_sector.asm --> boot sector
│ ├── disk_load.asm --> read from disk function
│ ├── kernel_entry.asm --> enter kernel - defines kernel_main
│ ├── print_32pm.asm --> protected mode print(used before using the kernel functions)
│ ├── print.asm --> real mode print
│ ├── print_hex.asm --> real mode print hex nums
│ └── switch_32pm.asm --> asm for switching to protected mode
├── drivers
│ ├── ports.c --> talking to ports through the functions here
│ ├── ports.h --> ports.c header file
│ ├── screen.c --> screen memory writing, cursor and print functions
│ └── screen.h --> screen.c header file
├── kernel
│ └── kernel_main.c --> the kernel main
└── Makefile
4 directories, 14 files
我設法找到了一個解決方案,即使不遵循傳統的編碼方式 - 它也有效.. 我只是使用asm函數中的代碼,因為它們手動內聯,為什么它在我不知道並且沒有任何線索之前不起作用如果有人有任何可能的想法,我想理解一個合理的解釋。 感謝任何試圖提供幫助的人!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.