我不建议海合会制定16条轨道守则。 海湾合作委员会的替代方案可以是:IA16-GCC项目,该项目是正在进行的工作,是实验性的。
由于需要在线集会,很难让海合会通过适当的实时守则。 如果你希望避免出现微妙的弊端,特别是当能够优化时,海湾合作委员会的内线集会就难以正确。 可在<>上填写。 我对此表示强烈反对。
页: 1 书刊只读出一个部门。 您的<代码>jmp kain 结束了对nel子如果实际上被装上记忆,那儿的记忆就会跳跃,但是,它被装上了,因此无法按预期开展工作。 http://www.ctyme.com/intr/rb-0607.htm
您的邮资库适当建立了分部登记册。 由于你正在使用海湾合作委员会,它期望CS=DS=ES=SS。 由于我们需要把数据输入记忆中,我们需要把 st放在安全的地方。 煤油将装上0x0000:0x7e00,这样我们就可以把 st放在0x0000:0x7c00的boot子下,在那里他们赢得了 t。 您需要用CLD
。 在此之前,要求海湾合作委员会这样做。 其中许多问题载于我的。 我的另一份Stackoverflowwer。
我们需要一份链接稿,以妥善记载记忆中的东西,并确保从一开始就向真实的C切入点kmain
发出指示。 我们还需要适当取消黑海经合组织科,因为海合会期望这样做。 联系人文字用于确定BASS部分的开始和结束。 <代码>0_bs 记到0x00。
<代码>Makefile可清理出一条轨道,以便于将来添加代码。 I ve amended the Code, so the Object file have based in the src
Directory. 这简化了处理程序。
When the real-mode code support was introduced and support added to GNU assembler it was enabled in GCC by using asm (".code16gcc");
. For quite some time now GCC has supported the -m16
option that does the same thing. With -m16
you don t need to add the .code16gcc
directive to the top of all the files.
我的斜体修改了在屏幕上打印<条码>a条码>的您的在线组件。 仅仅因为我没有改动,就意味着它没有问题。 由于登记被打上了布局,而编辑们则被告知,当优化时,登记册可能会导致奇怪的 b。 答复的第二部分表明,有一个机制,利用BIOS印刷特征,并通过适当的在线集会向青少年进行扼杀。
我建议编辑备选办法<代码>-Os -mregparm=3 -fomit-frame-pointer,以便优化空间。
<>:>
CROSSPRE=i686-elf-
CC=$(CROSSPRE)gcc
LD=$(CROSSPRE)ld
OBJCOPY=$(CROSSPRE)objcopy
DD=dd
NASM=nasm
DIR_SRC=src
DIR_BIN=bin
DIR_BUILD=build
KERNEL_NAME=jasos
KERNEL_BIN=$(DIR_BIN)/$(KERNEL_NAME).bin
KERNEL_ELF=$(DIR_BIN)/$(KERNEL_NAME).elf
BOOTLOADER_BIN=$(DIR_BIN)/bootloader.bin
BOOTLOADER_ASM=$(DIR_SRC)/bootloader.asm
DISK_IMG=$(DIR_BUILD)/disk.img
CFLAGS=-g -fno-PIE -static -std=gnu99 -m16 -Os -mregparm=3
-fomit-frame-pointer -nostdlib -ffreestanding -Wall -Wextra
LDFLAGS=-melf_i386
# List all object files here
OBJS=$(DIR_SRC)/god.o
.PHONY: all clean
all: $(DISK_IMG)
$(BOOTLOADER_BIN): $(BOOTLOADER_ASM)
$(NASM) -f bin $< -o $@
%.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
$(KERNEL_ELF): $(OBJS)
$(LD) $(LDFLAGS) -Tlink.ld $^ -o $@
$(KERNEL_BIN): $(KERNEL_ELF)
$(OBJCOPY) -O binary $< $@
$(DISK_IMG): $(KERNEL_BIN) $(BOOTLOADER_BIN)
$(DD) if=/dev/zero of=$@ bs=1024 count=1440
$(DD) if=$(BOOTLOADER_BIN) of=$@ conv=notrunc
$(DD) if=$(KERNEL_BIN) of=$@ conv=notrunc seek=1
clean:
rm -f $(DIR_BIN)/*
rm -f $(DIR_BUILD)/*
rm -f $(DIR_SRC)/*.o
link.ld:
OUTPUT_FORMAT("elf32-i386");
ENTRY(kmain);
SECTIONS
{
. = 0x7E00;
.text.main : SUBALIGN(0) {
*(.text.bootstrap);
*(.text.*);
}
.data.main : SUBALIGN(4) {
*(.data);
*(.rodata*);
}
.bss : SUBALIGN(4) {
__bss_start = .;
*(.COMMON);
*(.bss)
}
. = ALIGN(4);
__bss_end = .;
__bss_sizel = ((__bss_end)-(__bss_start))>>2;
__bss_sizeb = ((__bss_end)-(__bss_start));
/DISCARD/ : {
*(.eh_frame);
*(.comment);
}
}
<>strong>src/god.c:
#include <stdint.h>
/* The linker script ensures .text.bootstrap code appears first.
* The code simply jumps to our real entrypoint kmain */
asm (".pushsection .text.bootstrap
"
"jmp kmain
"
".popsection");
extern uintptr_t __bss_start[];
extern uintptr_t __bss_end[];
/* Zero the BSS section */
static inline void zero_bss()
{
uint32_t *memloc = __bss_start;
while (memloc < __bss_end)
*memloc++ = 0;
}
/* JASOS kernel C entrypoint */
void kmain()
{
/* We need to zero out the BSS section */
zero_bss();
asm (
"movb $0, %dl;"
"inc %dh;"
"movb $2, %ah;"
"movb $0, %bh;"
"int $0x10;"
"movb $ a , %al;"
"movb $10, %ah;"
"movw $1, %cx;"
"int $0x10;"
);
return;
}
<>strong>src/roomloader.asm:
; Allows our code to be run in real mode.
BITS 16
ORG 0x7c00
_start:
xor ax, ax ; DS=ES=0
mov ds, ax
mov es, ax
mov ss, ax ; SS:SP=0x0000:0x7c00
mov sp, 0x7c00
cld ; Direction flag = 0 (forward movement)
; Needed by code generated by GCC
; Read 17 sectors starting from CHS=(0,0,2) to 0x0000:0x7e00
; 17 * 512 = 8704 bytes (good enough to start with)
mov bx, 0x7e00 ; ES:BX (0x0000:0x7e00) is memory right after bootloader
mov ax, 2<<8 | 17 ; AH=2 Disk Read, AL=17 sectors to read
mov cx, 0<<8 | 2 ; CH=Cylinder=0, CL=Sector=2
mov dh, 0 ; DH=Head=0
int 0x13 ; Do BIOS disk read
jmp 0x0000:Start ; Jump to start set CS=0
; Moves the cursor to row dl, col dh.
MoveCursor:
mov ah, 2
mov bh, 0
int 10h
ret
; Prints the character in al to the screen.
PrintChar:
mov ah, 10
mov bh, 0
mov cx, 1
int 10h
ret
; Set cursor position to 0, 0.
ResetCursor:
mov dh, 0
mov dl, 0
call MoveCursor
ret
Start:
call ResetCursor
; Clears the screen before we print the boot message.
; QEMU has a bunch of crap on the screen when booting.
Clear:
mov al,
call PrintChar
inc dl
call MoveCursor
cmp dl, 80
jne Clear
mov dl, 0
inc dh
call MoveCursor
cmp dh, 25
jne Clear
; Begin printing the boot message.
Msg:
call ResetCursor
mov si, BootMessage
NextChar:
lodsb
call PrintChar
inc dl
call MoveCursor
cmp si, End
jne NextChar
call dword 0x7e00 ; Because GCC generates code with stack
; related calls that are 32-bits wide we
; need to specify `DWORD`. If we don t, when
; kmain does a `RET` it won t properly return
; to the code below.
; Infinite ending loop when kmain returns
cli
.endloop:
hlt
jmp .endloop
BootMessage: db "Booting..."
End:
; Zerofill up to 510 bytes
times 510 - ($ - $$) db 0
; Boot Sector signature
dw 0AA55h
创建了1.44MiB floppy磁盘图像,称为build/disk.img
。 它可以在QEMU进行指挥,如:
qemu-system-i386 -fda build/disk.img
预期产出应类似于:
Proper use of Inline Assembly to Write a String Using the BIOS
更复杂的法典文本: 下表列出了海合会扩展在线组群。 答案并不是要讨论海合会延展的在线组装使用,但网上有rel=“noreferer”。 应当指出,there是许多不好的建议、文件、辅导和抽样守则,其中存在问题,这些人员可能根本不了解这个问题。 <<>Yousup>
<>:>
CROSSPRE=i686-elf-
CC=$(CROSSPRE)gcc
LD=$(CROSSPRE)ld
OBJCOPY=$(CROSSPRE)objcopy
DD=dd
NASM=nasm
DIR_SRC=src
DIR_BIN=bin
DIR_BUILD=build
KERNEL_NAME=jasos
KERNEL_BIN=$(DIR_BIN)/$(KERNEL_NAME).bin
KERNEL_ELF=$(DIR_BIN)/$(KERNEL_NAME).elf
BOOTLOADER_BIN=$(DIR_BIN)/bootloader.bin
BOOTLOADER_ASM=$(DIR_SRC)/bootloader.asm
DISK_IMG=$(DIR_BUILD)/disk.img
CFLAGS=-g -fno-PIE -static -std=gnu99 -m16 -Os -mregparm=3
-fomit-frame-pointer -nostdlib -ffreestanding -Wall -Wextra
LDFLAGS=-melf_i386
# List all object files here
OBJS=$(DIR_SRC)/god.o $(DIR_SRC)/biostty.o
.PHONY: all clean
all: $(DISK_IMG)
$(BOOTLOADER_BIN): $(BOOTLOADER_ASM)
$(NASM) -f bin $< -o $@
%.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
$(KERNEL_ELF): $(OBJS)
$(LD) $(LDFLAGS) -Tlink.ld $^ -o $@
$(KERNEL_BIN): $(KERNEL_ELF)
$(OBJCOPY) -O binary $< $@
$(DISK_IMG): $(KERNEL_BIN) $(BOOTLOADER_BIN)
$(DD) if=/dev/zero of=$@ bs=1024 count=1440
$(DD) if=$(BOOTLOADER_BIN) of=$@ conv=notrunc
$(DD) if=$(KERNEL_BIN) of=$@ conv=notrunc seek=1
clean:
rm -f $(DIR_BIN)/*
rm -f $(DIR_BUILD)/*
rm -f $(DIR_SRC)/*.o
link.ld:
OUTPUT_FORMAT("elf32-i386");
ENTRY(kmain);
SECTIONS
{
. = 0x7E00;
.text.main : SUBALIGN(0) {
*(.text.bootstrap);
*(.text.*);
}
.data.main : SUBALIGN(4) {
*(.data);
*(.rodata*);
}
.bss : SUBALIGN(4) {
__bss_start = .;
*(.COMMON);
*(.bss)
}
. = ALIGN(4);
__bss_end = .;
__bss_sizel = ((__bss_end)-(__bss_start))>>2;
__bss_sizeb = ((__bss_end)-(__bss_start));
/DISCARD/ : {
*(.eh_frame);
*(.comment);
}
}
src/biostty.c:
#include <stdint.h>
#include "../include/biostty.h"
void fastcall
writetty_str (const char *str)
{
writetty_str_i (str);
}
void fastcall
writetty_char (const uint8_t outchar)
{
writetty_char_i (outchar);
}
include/x86helper.h:
#ifndef X86HELPER_H
#define X86HELPER_H
#include <stdint.h>
#define STR_TEMP(x) #x
#define STR(x) STR_TEMP(x)
#define TRUE 1
#define FALSE 0
#define NULL (void *)0
/* regparam(3) is a calling convention that passes first
three parameters via registers instead of on stack.
1st param = EAX, 2nd param = EDX, 3rd param = ECX */
#define fastcall __attribute__((regparm(3)))
/* noreturn lets GCC know that a function that it may detect
won t exit is intentional */
#define noreturn __attribute__((noreturn))
#define always_inline __attribute__((always_inline))
#define used __attribute__((used))
/* Define helper x86 function */
static inline void fastcall always_inline x86_hlt(void){
__asm__ ("hlt
");
}
static inline void fastcall always_inline x86_cli(void){
__asm__ ("cli
");
}
static inline void fastcall always_inline x86_sti(void){
__asm__ ("sti
");
}
static inline void fastcall always_inline x86_cld(void){
__asm__ ("cld
");
}
/* Infinite loop with hlt to end bootloader code */
static inline void noreturn fastcall haltcpu()
{
while(1){
x86_hlt();
}
}
#endif
include/biostty.h:
#ifndef BIOSTTY_H
#define BIOSTTY_H
#include <stdint.h>
#include "../include/x86helper.h"
/* Functions ending with _i are always inlined */
extern fastcall void
writetty_str (const char *str);
extern fastcall void
writetty_char (const uint8_t outchar);
static inline fastcall always_inline void
writetty_char_i (const uint8_t outchar)
{
__asm__ ("int $0x10
"
:
: "a"(((uint16_t)0x0e << 8) | outchar),
"b"(0x0000));
}
static inline fastcall always_inline void
writetty_str_i (const char *str)
{
/* write characters until we reach nul terminator in str */
while (*str)
writetty_char_i (*str++);
}
#endif
<>strong>src/god.c:
#include <stdint.h>
#include "../include/biostty.h"
/* The linker script ensures .text.bootstrap code appears first.
* The code simply jumps to our real entrypoint kmain */
asm (".pushsection .text.bootstrap
"
"jmp kmain
"
".popsection");
extern uintptr_t __bss_start[];
extern uintptr_t __bss_end[];
/* Zero the BSS section */
static inline void zero_bss()
{
uint32_t *memloc = __bss_start;
while (memloc < __bss_end)
*memloc++ = 0;
}
/* JASOS kernel C entrypoint */
void kmain()
{
/* We need to zero out the BSS section */
zero_bss();
writetty_str("
Hello, world!
");
return;
}
连接器的文字和boot子从本回答中提出的第一版没有修改。
在基欧马斯大学经营时,产出应类似于:
Footnotes:
<>1> https://www.codeproject.com/Articles/664165/Writing-a-officeer-in-Assembly-and-C-Part” rel=“noretinger”>“在C中打上一个载荷”是《法典》项目指南。 它被评为很高的等级,在某一点上逐月发表。 Unfortunitely 和许多涉及在线集会的教员一样,他们教授许多不良习惯,并做错东西。 他们很幸运,可以与他们确实使用的汇编商合作。 许多人试图利用这些坏想法与海合会合写真实的ker子,并且错失。 我将《法典》项目提一下,因为它过去是许多关于证券流通问题的基础。 如同许多其他理论一样,它实际上完全可以信赖。 其中一个例外是:。 C中带有gcc的真正模式:写上载荷。
我提供了第二部法典样本,作为微小的完全可核查的范例,以显示海合会在网上集会上想要印刷一种特性并印刷一部插图。 那里很少有条款表明如何适当利用海湾合作委员会。 第二个例子表明,在C职能范围内撰写的组装编码与撰写C功能之间有差别,如书目信息系统电话等所需物品的组装低。 如果您将使用GCC,以总结整个组装规范职能,那么,从编组的职能开始,就很难写上文字。 这违背了使用C的目的。