Tag: 操作系统

为什么数据类型的大小会随着操作系统的变化而变化?

在一次采访中我问过这个问题,在某些操作系统中, char大小是2个字节,但在某些操作系统中它是4个字节或不同。 为什么会这样? 为什么它与其他基本类型不同,例如int ?

在保护模式下设置中断(x86)

为保护模式设置中断的过程是什么? 这个链接说应该: 为中断描述符表腾出空间 告诉CPU该空间在哪里(参见GDT教程:lidt的工作方式与lgdt完全相同) 告诉PIC您不再需要使用BIOS默认值(请参阅编程PIC芯片) 为IRQ和exception编写几个ISR处理程序(请参阅中断服务程序) 将ISR处理程序的地址放在适当的描述符中 启用IRQ掩码中所有支持的中断(PIC) 第三步对我没有任何意义(我查看了这个链接,但没有任何关于告诉PIC的事情)所以我忽略了它并完成了接下来的两个步骤,当我到达最后一步时再次无能为力。 但是,根据我对中断的理解,我不理解的两个步骤都与PIC控制器的硬件中断有关,不应该影响PIT在IRQ 0上引发的中断。因此我也忽略了这一步骤。 当我运行我的代码时,它编译得很好,甚至在虚拟机中运行,但中断似乎只发射一次。 然后我意识到我没有向EOI发送EOI,以防止它再引发任何中断。 但是,在iret指令使虚拟机崩溃之前,添加mov al, 0x20和out 0x20, al 。 这是我的IDT: ; idt idt_start : dw 0x00 ; The interrupt handler is located at absolute address 0x00 dw CODE_SEG ; CODE_SEG points to the GDT entry for code db 0x0 ; The unused byte db 0b11101001 […]

为什么stackoverflow错误混乱?

这个简单的C程序很少在相同的调用深度终止: #include #include void recursive(unsigned int rec); int main(void) { recursive(1); return 0; } void recursive(unsigned int rec) { printf(“%u\n”, rec); recursive(rec + 1); } 这种混乱行为背后的原因是什么? 我使用fedora(16GiB ram,堆栈大小为8192),并使用cc编译,没有任何选项。 编辑 我知道这个程序会抛出一个stackoverflow 我知道启用一些编译器优化会改变行为,程序将达到整数溢出。 我知道这是未定义的行为,这个问题的目的是理解/获得可能解释我们在那里观察到的实现特定内部行为的概述。 问题更多,因为在Linux上,线程堆栈大小是固定的并由ulimit -s给出,会影响可用的堆栈大小,以便堆栈溢出并不总是出现在相同的调用深度? 编辑2 @BlueMoon总是在他的CentOS上看到相同的输出,而在我的Fedora上,堆栈为8M,我看到不同的输出(最后打印的整数261892或261845,或261826,或……)

为什么在中断处理程序中使用自旋锁

我想知道为什么在中断处理程序中使用自旋锁而不是信号量。

堆栈内存是否有限制?

我正在经历其中一个主题。 一个程序崩溃了,因为它在函数内部声明了一个10 ^ 6的数组。 给出的原因是堆栈上的内存分配失败导致崩溃。 当全局声明相同的数组时,它运行良好。(堆上的内存保存了它)。 现在,让我们假设,堆栈向下增长并向上堆积。 我们有: – -堆 – – ——————- – -堆 – – 现在,我相信如果堆栈上的分配失败,它也必须在堆上失败。 所以我的问题是:堆栈大小有限制吗? (超过限制导致程序崩溃)。 或者我错过了什么?

哪里用volatile?

我读过volatile关键字,但我不知道在什么情况下我应该使用它。 当内存(变量)得到更新并且进程没有意识到这一点? 在什么情况下驱动程序应该使用volatile变量?

fork()系统调用和进程的内存空间

我引用“当进程使用fork()调用创建一个新进程时,只有父进程和新分叉的子进程之间共享共享内存段。堆栈和堆的副本是为新创建的进程”从Silberschatz的“操作系统概念”解决方案。 但是当我尝试这个程序的时候 #include #include #define MAX_COUNT 200 void ChildProcess(void); /* child process prototype */ void ParentProcess(void); /* parent process prototype */ void main(void) { pid_t pid; char * x=(char *)malloc(10); pid = fork(); if (pid == 0) ChildProcess(); else ParentProcess(); printf(“the address is %p\n”,x); } void ChildProcess(void) { printf(” *** Child process ***\n”); } void […]

对象文件平台是否独立?

是否可以在一个平台上编译程序并与其他平台链接? 对象文件包含什么? 我们可以将可执行文件脱钩以生成目标文件吗?

如何在编译/链接时使用地址进行计算?

我写了一些用于初始化IDT的代码,它将32位地址存储在两个不相邻的16位半中。 IDT可以存储在任何地方,并通过运行LIDT指令告诉CPU在哪里。 这是初始化表的代码: void idt_init(void) { /* Unfortunately, we can’t write this as loops. The first option, * initializing the IDT with the addresses, here looping over it, and * reinitializing the descriptors didn’t work because assigning a * a uintptr_t (from (uintptr_t) handler_func) to a descr (aka * uint64_t), according to the compiler, “isn’t […]

是否严格要求组装成为操作系统的“最低”部分?

我是一名中级(抽象)程序员,几个月前我开始考虑是否应该减少或增加抽象(我选择减少)。 现在,我想我已经做了大部分关于我需要的“研究”,但仍然有一些问题。 现在,虽然我“无所事事”,我只是加强了我的C技能(买了“K&R C编程朗”),并且我想(感觉舒服之后)开始学习操作系统(如minix)只是为了学习目的,但我有一个想法困在我的脑海里,我真的不知道我是否应该关心。 理论上(我认为,不确定),更高级别的语言不能直接引用硬件(如寄存器,内存位置等),因此基础的“完美语言”将是汇编。 我已经研究过汇编(前一段时间)只是为了看看它是怎么回事(由于本书使用了过时的调试器(对于Linux来说,汇编语言一步一步),我已经停在本书的中间但是从我的内容读过,我不喜欢这门语言。 所以问题很简单:操作系统(引导程序/内核)是否可以在不触及单行程序的情况下进行编程,并且仍然有效? 即使它可以,它也不会是“跨架构”,不是吗? (i386 / arm / mips等…) 感谢您的支持