小编Pan*_*der的帖子

在不使用C库的情况下在0xb8000处显示文本视频内存

我一直在用C编写内核.我一直在使用GCC交叉编译器,在Windows系统上编写并以16位实模式为目标.我没有可用于编写内核的C库.我已经开始使用一些代码来假设将字符直接打印到屏幕上.这是一个函数来自kernel.c:

int main()
{
  char *src = (char *)0xB8000000L;
  *src = 'M';
  src += 2;
  *src = 'D';
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用GCC编译了我的代码,并使用参数-m16生成将在实模式下运行的代码.我使用这些命令来生成我的kernel.bin:

gcc -ffreestanding -c -m16 kernel.c -o kernel.o
ld -Ttext 0x10000 -o kernel.pe kernel.o
objcopy -O binary kernel.pe kernel.bin
Run Code Online (Sandbox Code Playgroud)

Stack Overflow用户Michael Petch解决了我的链接器问题,但评论代码本身是不正确的.他发表了这样的评论:

除链接器问题外,您是否尝试将旧的TurboC/MSVC 16位代码转换为GCC?我发现(char*)0xB8000000L可疑.如果它是一个真正的16位C编译器,它可能是好的,如果它是(char far*)0xB8000000L.GCC不是一个真正的16位C编译器,并没有旧式远指针的概念.所以,即使你得到这个代码进行编译,这可能不会做你认为它做的,我假设从-m16选项与GCC你正在尝试创建一个实模式16位内核(而不是保护模式一个) )?

我一直在尝试printf在C中为我自己的操作系统实现自己的类似功能.我上面提供的代码只是我理解的一小部分.我在程序集中创建了一个bootloader(8086).

迈克尔是对的吗?如果是这样,我该如何解决这个问题并直接写入视频内存0xb8000

assembly kernel real-mode osdev x86-16

4
推荐指数
1
解决办法
1349
查看次数

定义全局描述符表有什么用?

我阅读了关于GDT(全局描述符表)的教程,该教程将GDT定义为"为内存的某些部分定义基本访问权限的那个".这意味着GDT用于记忆保护.

它是否执行除上述以外的任何其他任务?

是否必须在操作系统中实施GDT?

简而言之,如果有人能够以易于理解的方式详细阐述GDT,那将会更好.

谢谢

x86 assembly operating-system kernel gdt

4
推荐指数
1
解决办法
2743
查看次数

使用gcc编译时,函数和变量前面是否为"_"?

我正在使用GCC在Linux环境中学习OS开发.我在Bran的内核开发中了解到,编译时C中的所有函数和变量名都在其相应的汇编源文件中以"_"(下划线)开头.但是当我浏览已编译的C程序的汇编源代码时,我甚至找不到"_main"函数.我执行了以下操作.

cpp sample.c sample.i

gcc -S sample.I

c gcc operating-system kernel

4
推荐指数
1
解决办法
336
查看次数

在一个简单的C程序中使用gets()来利用Buffer Overflow

我是Buffer Overflow漏洞的新手,我从一个简单的C程序开始.

#include <stdio.h>
#include <strings.h>


void execs(void){
    printf("yay!!");
}

void return_input (void)
{
    char array[30];
    gets(array);
}

int main()
{
    return_input();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译阶段

我通过禁用stack protectoras来编译上面的cc程序:

cc test.c -o test -fno-stack-protector
Run Code Online (Sandbox Code Playgroud)

使用elf文件的转储objdump如下:

0804843b <execs>:
 804843b:   55                      push   %ebp
 804843c:   89 e5                   mov    %esp,%ebp
 804843e:   83 ec 08                sub    $0x8,%esp
 8048441:   83 ec 0c                sub    $0xc,%esp
 8048444:   68 10 85 04 08          push   $0x8048510
 8048449:   e8 b2 fe ff ff          call   8048300 <printf@plt>
 804844e: …
Run Code Online (Sandbox Code Playgroud)

c exploit gets buffer-overflow

4
推荐指数
1
解决办法
3918
查看次数

A20线在保护模式下扮演什么角色?

我正在经历x86的保护模式部分.我刚刚了解了GDT.之前,我已经研究过进入保护模式(即:使用所有32位地址线)必须启用A20门.那么,启用A20的代码必须是16位吗?最近,当我浏览wiki.osdev网站时,我发现启用A20的代码是用x86汇编编写的.X86汇编产生的32位操作码无法以16位模式加载吗?

请尽可能解释.谢谢.

x86 assembly operating-system kernel gdt

3
推荐指数
1
解决办法
312
查看次数

为什么有必要在AT&T组装中使用"$"符号?

我是汇编语言的新手.我最近陷入了悲惨的境地.我创建了一个示例汇编程序,如下所示:

head.h

#define _Length_ 0x0A
Run Code Online (Sandbox Code Playgroud)

电源

movw $_LENGTH_, %ax
movw _LENGTH_, %ax
Run Code Online (Sandbox Code Playgroud)

现在两个MOV语句有什么区别?斧头的价值是什么?

我正在使用Ubuntu和GAS汇编程序(AT&T语法).

提前致谢

x86 assembly gnu-assembler x86-16

2
推荐指数
1
解决办法
108
查看次数

Rust 引用如何存储在内存中(特别是堆栈)

我一直在学习 Rust 中的引用,发现很难理解引用到底是如何存储在堆栈中的。

考虑下面的程序:

fn main() {
    let name = String::from("Somu");
    let name_ref = &name;
}
Run Code Online (Sandbox Code Playgroud)

现在,如何在堆栈帧中为这两个变量分配内存?

|--------------------|
| name     | 0x1fcd  |
|--------------------|
| name_ref | ?       |
|--------------------|
Run Code Online (Sandbox Code Playgroud)

因此,由于String存储在堆中,因此我们有堆的地址,其中字符串“Somu”作为变量的值出现name

现在,name_ref是对 的引用name。用 Rust 术语来说,name_ref借用 指向的值name

那么,什么 get 作为 的值存储在堆栈帧中呢name_ref

  • 包含字符串的堆内存的地址?
  • name堆栈中的地址?

或者是其他东西?

有人可以用这个概念丰富我吗?

提前致谢

rust rust-cargo borrow-checker

2
推荐指数
1
解决办法
521
查看次数

PM中Selector和GDT之间的关系是什么?

我浏览了网上有关全局描述符表的许多教程.但我找不到一个详细解释64位描述符中所有字段的站点.此外,我坚持使用GDT中的选择器概念.我知道选择器有一个索引,TI是GDT还是LDT字段.简单来说,选择器与GDT之间的关系是什么?如果可能请详细说明.

谢谢..

assembly operating-system kernel selector gdt

1
推荐指数
1
解决办法
353
查看次数

`asm()`函数如何在C语言中工作?

我正在学习操作系统开发和课程初学者.我想在实模式环境中构建我的系统,这是一个使用C语言的16位环境.

在C中,我使用函数asm()将代码转换为16位,如下所示:

asm(".code16")
Run Code Online (Sandbox Code Playgroud)

在GCC的语言中生成16位可执行文件(不完全如此).

题:

假设我有两个头文件head1.hhead2.hmain.c文件.main.c文件内容如下:

asm(".code16");
#include<head1.h>
#include<head2.h>
int main(){
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在,自从我开始我的代码的命令生成16位可执行文件,然后包括head1.hhead2.h,我需要做的,我创建的所有头文件一样吗?(或)添加asm(".code16");一次是否足够?

操作系统:Ubuntu

编译器:Gnu CC

assembly gcc operating-system kernel bootloader

1
推荐指数
1
解决办法
1428
查看次数

什么是细分以及如何在8086模式下解决这些问题?

自从我开始使用8086汇编语言编程以来,我一直在思考这些段和段寄存器.我面临的问题是,我无法看到我脑海中存在哪些细分的视觉图像,因此这些概念对我来说并不清楚.


  • 任何人都可以帮助我理解将其与现实世界场景相关联的概念吗?我还有以下问题:

问题1:

据我所知,在启用了20地址线的16位实模式下,我们可以将物理内存分成16段,每段64KiB.第一部分开始于0x00000.下一段的起始地址是什么.是否会添加0x10000(65536 = 64KiB)?

问题2:

这个问题有点奇怪,但仍然是我唯一的选择.假设我给了一个偏移地址0x6000,我怎样才能找到它所属的段以便解决它.

谢谢

x86 assembly operating-system kernel x86-16

1
推荐指数
2
解决办法
1291
查看次数

哪种寻址方式用于访问磁盘?

我正在学习OS开发,我处于初级水平.我创建了一个简单的启动加载器 要访问磁盘上的其他文件(比如HDD或USB驱动器),我应该使用哪种寻址模式?(CHS或LBA或INT 13h扩展).

哪种寻址方式非常有效(手段,可以用于大多数驱动器)?

谢谢

x86 assembly kernel disk-access bootloader

-1
推荐指数
1
解决办法
136
查看次数

如何通过编程语言实现多处理?

我正在尝试开发一个简单的操作系统.到目前为止,我开发的所有程序都可以在一个处理器中运行.但是当我通过一个名为多处理系统的概念时,几乎所有的最新系统都基于这个概念,我有很多疑问.

首先,如何创建可在多处理器系统中运行的程序.它是硬件导向还是程序员特定的?

其次,我学习了并行编程语言,这在多处理系统中很有用,其中Java是一个但C不是.那么在C(Windows)中开发的操作系统如何才能实现多处理?

谢谢.

c assembly operating-system kernel multiprocessing

-3
推荐指数
2
解决办法
1216
查看次数