C语言 强制转换后函数指针为0

8xiog9wr  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(112)

我正在尝试开发自己的操作系统。在设置IDT时,我想像这样使用&isr0获取ISR 0函数的地址:

//The example function
void isr0() {
    volatile uint8_t* ptr1 = (uint8_t*)(0xB8000);
    ptr1[0] = 'A';
}
void main(){
    int ptr = (int)&isr0;
    volatile uint8_t* ptr1 = (uint8_t*)0xB8000;
    int offset2 = 40;
    int value = (int)ptr;
    ptr1[0 + offset2] = 48 + (value/100000) % 10;
    ptr1[2 + offset2] = 48 + (value/10000) % 10;
    ptr1[4 + offset2] = 48 + (value/1000) % 10;
    ptr1[6 + offset2] = 48 + (value/100) % 10;
    ptr1[8 + offset2] = 48 + (value/10) % 10;
    ptr1[10+ offset2] = 48 + (value/1) % 10;
    while(1);
    ...
}

字符串
它的输出是000000。
x1c 0d1x的数据
在普通的Linux机器上,它可以毫无问题地向我显示内存位置。
另外,我注意到,当我尝试创建函数指针,然后调用函数指针时,它确实工作;然而,当我尝试获取它的值时,它就不工作了。(&isr0不可能是一个问题,问题是如何将它解析成int。)
有谁能告诉我为什么会这样,以及如何修复它?

编译步骤

i686-elf-gcc -nostdlib -O3 -ffreestanding -Wall -Wextra -m32 -c kernel.c -o bin/stage4.bin
objcopy -O binary bin/stage4.bin bin/stage5.bin

编译这两个使用:

nasm stage1.asm -f bin -o bin/stage1.bin


然后把所有的东西放在一起:

cat bin/stage1.bin bin/stage2.bin bin/stage5.bin > bin/stage3.bin
qemu-system-x86_64 -fda bin/stage3.bin -vga vmware  -d guest_errors -m 64M >> bin/a 2>&1

cvxl0en2

cvxl0en21#

i686-elf-gcc -nostdlib -O3 -ffreestanding -Wall -Wextra -m32 -c kernel.c -o bin/stage4.bin 
objcopy -O binary bin/stage4.bin bin/stage5.bin

字符串
gcc -c产生一个可重定位的目标文件,你错误地将其命名为stage4.bin而不是.o,它不包含对象在内存中需要的位置的实际地址;相反,它在一个占位符中(可能为0),并有一个单独的重定位表,以通知链接器的名称的符号,其地址应该去那里。你只需要将objcopy转换成二进制,这只会丢弃重定位表,并留下0占位符占用的内存位置。
你必须在你的目标文件上运行链接器来解析所有这些引用,并使用适当的链接器脚本构建一个可执行文件。一些例子见https://wiki.osdev.org/Linker_Scripts。然后你可以将objcopy转换为二进制。

相关问题