相关疑难解决方法(0)

试图了解主要的反汇编指令

嗨,我已经拆解了一些程序(linux),我写的是为了更好地理解它是如何工作的,我注意到主要功能始终以:

lea    ecx,[esp+0x4] ; I assume this is for getting the adress of the first argument of the main...why ?
and    esp,0xfffffff0 ; ??? is the compiler trying to align the stack pointer on 16 bytes ???
push   DWORD PTR [ecx-0x4] ; I understand the assembler is pushing the return adress....why ?
push   ebp                
mov    ebp,esp
push   ecx  ;why is ecx pushed too ??
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:为什么所有这些工作都完成了?我只了解使用:

push   ebp                
mov    ebp,esp
Run Code Online (Sandbox Code Playgroud)

其余对我来说似乎毫无用处......

linux compiler-construction x86 assembly gcc

17
推荐指数
2
解决办法
3966
查看次数

如何用C语言编写linux启动代码?

我是学习OS开发的新手.从我读过的书中,它说启动加载器会将第一个MBR复制到0x7c00,然后从实模式开始.

并且,示例从16位汇编代码开始.但是,当我查看今天的linux内核时,arch/x86/boot有'header.S'和'boot.h',但实际代码是在main.c中实现的.

这似乎对"不编写汇编"很有用.但是,这是如何在Linux中专门完成的?我可以粗略地想象可能有特殊gcc选项和链接策略,但我看不到细节.

c assembly linux-kernel bootloader x86-16

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

在不使用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
查看次数