Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么一般程序通常从0x8000开始?_C++_C_Linker_Bootloader - Fatal编程技术网

C++ 为什么一般程序通常从0x8000开始?

C++ 为什么一般程序通常从0x8000开始?,c++,c,linker,bootloader,C++,C,Linker,Bootloader,我对引导加载程序和系统软件并不陌生,但我不知道为什么通用程序从0x8000开始。我已经知道地址0x8000在普通C/C++程序中被用作起始地址 一般程序的引导加载程序的最小大小是否达到0x8000?或者应该分配给引导加载程序的ROM的最小块大小是32KB?还是有其他原因 我想从历史上或逻辑上,从虚拟地址的角度了解这一点 我感谢大家,感谢你们的时间和帮助。 为了让问题更清楚,这个问题与虚拟地址有关,而不是与物理地址有关 从物理内存地址的角度来看,我基本上同意R的观点 不用说一个不同的特定系统,例

我对引导加载程序和系统软件并不陌生,但我不知道为什么通用程序从
0x8000
开始。我已经知道地址
0x8000
在普通C/C++程序中被用作起始地址

一般程序的引导加载程序的最小大小是否达到
0x8000
?或者应该分配给引导加载程序的ROM的最小块大小是32KB?还是有其他原因

我想从历史上或逻辑上,从虚拟地址的角度了解这一点


我感谢大家,感谢你们的时间和帮助。 为了让问题更清楚,这个问题与虚拟地址有关,而不是与物理地址有关

从物理内存地址的角度来看,我基本上同意R的观点

不用说一个不同的特定系统,例如linux(甚至在android中)、通用RTO(nucleus和其他,特别是ARM链接器部分),它们都使用地址0x8000作为通用程序的起始地址。 例如位于0x0的crt_begin.o、crt.o等,此区域中存在加载程序

因此,考虑到块大小,我猜一般程序的引导加载程序的最小大小是32KB,如果它在引导时位于BootROM(冷引导)


嗯,但我不确定…

一般来说,在除了最小的嵌入式系统之外的所有嵌入式系统上,平台ABI设计器都希望避免使用最低地址,以便捕获空指针解引用。如果空指针与数组或结构成员偏移量解除引用,那么拥有几个KB的无效地址会给您带来一些额外的安全性,如
null\u ptr->some\u member

它取决于系统,程序从不同的地址启动 不同的系统。在Unix下,这是常见的(甚至可能是 Posix)使用地址0作为空指针,并且不映射 虚拟内存的第一页,以便取消对空指针的引用 导致段冲突。我怀疑其他系统正在使用 地址0作为空指针的行为类似(但它们保留了多少空间 可能会有所不同)。(历史上,通常将第一页映射为已读) 仅,并用零填充它,这样做空指针的行为就好像 它是一个空字符串,一个指向
”的指针。大约是25 然而,这需要几年的时间。)

我希望即使在今天,一些嵌入式系统也能加载
从地址0开始的程序。

我怀疑在很多情况下,前32K是为监视器代码/ram使用而保留的。在许多8051 eval板中,根据常驻监视器(有些还用作调试器),所有应用程序的默认值为0x1000或0x2000并不少见


32K可能是您的u-boot/etc加载程序空间。

这有点随意,在linux上,至少由链接器决定。一般的想法是保留一些空间来捕获空指针异常。为了帮助防止内核空间空指针取消引用在内核模式下执行任意用户代码,linux阻止您映射内存的最底层
/proc/sys/vm/mmap_min_addr
控制可以映射的最低地址(如果愿意,可以将其更改为0并将页面映射为0)

在linux上,您可以通过查看
/proc
查看内存映射。比如说,

genwitt ~> cat /proc/self/maps 00400000-0040c000 r-xp 00000000 08:01 354804 /bin/cat 0060b000-0060c000 r--p 0000b000 08:01 354804 /bin/cat 0060c000-0060d000 rw-p 0000c000 08:01 354804 /bin/cat 01dda000-01dfb000 rw-p 00000000 00:00 0 [heap] 7f5b25913000-7f5b25a97000 r-xp 00000000 08:01 435953 /lib64/libc-2.14.1.so 7f5b25a97000-7f5b25c97000 ---p 00184000 08:01 435953 /lib64/libc-2.14.1.so 7f5b25c97000-7f5b25c9b000 r--p 00184000 08:01 435953 /lib64/libc-2.14.1.so 7f5b25c9b000-7f5b25c9c000 rw-p 00188000 08:01 435953 /lib64/libc-2.14.1.so 7f5b25c9c000-7f5b25ca1000 rw-p 00000000 00:00 0 7f5b25ca1000-7f5b25cc2000 r-xp 00000000 08:01 436061 /lib64/ld-2.14.1.so 7f5b25cd2000-7f5b25e97000 r--p 00000000 08:01 126248 /usr/lib64/locale/locale-archive 7f5b25e97000-7f5b25e9a000 rw-p 00000000 00:00 0 7f5b25ec0000-7f5b25ec1000 rw-p 00000000 00:00 0 7f5b25ec1000-7f5b25ec2000 r--p 00020000 08:01 436061 /lib64/ld-2.14.1.so 7f5b25ec2000-7f5b25ec3000 rw-p 00021000 08:01 436061 /lib64/ld-2.14.1.so 7f5b25ec3000-7f5b25ec4000 rw-p 00000000 00:00 0 7fff18c37000-7fff18c58000 rw-p 00000000 00:00 0 [stack] 7fff18d0c000-7fff18d0d000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] genwitt~>cat/proc/self/maps 00400000-0040c000 r-xp 00000000 08:01 354804/bin/cat 0060b000-0060c000 r--p 0000b000 08:01 354804/bin/cat 0060c000-0060d000 rw-p 0000c000 08:01 354804/bin/cat 01dda000-01dfb000 rw-p 00000000:00[堆] 7f5b25913000-7f5b25a97000 r-xp 00000000 08:01 435953/lib64/libc-2.14.1.so 7f5b25a97000-7f5b25c97000---p 00184000 08:01 435953/lib64/libc-2.14.1.so 7f5b25c97000-7f5b25c9b000 r--p 00184000 08:01 435953/lib64/libc-2.14.1.so 7f5b25c9b000-7f5b25c9c000 rw-p 00188000 08:01 435953/lib64/libc-2.14.1.so 7f5b25c9c000-7f5b25ca1000 rw-p 00000000:00 7f5b25ca1000-7f5b25cc2000 r-xp 00000000 08:01 436061/lib64/ld-2.14.1.so 7f5b25cd2000-7f5b25e97000 r--p 00000000 08:01 126248/usr/lib64/locale/locale归档 7f5b25e97000-7F5B25E9A0000 rw-p 00000000:00 7f5b25ec0000-7f5b25ec1000 rw-p 00000000:00 7f5b25ec1000-7f5b25ec2000 r--p 00020000 08:01 436061/lib64/ld-2.14.1.so 7f5b25ec2000-7f5b25ec3000 rw-p 00021000 08:01 436061/lib64/ld-2.14.1.so 7f5b25ec3000-7f5b25ec4000 rw-p 00000000:00 7fff18c37000-7fff18c58000 rw-p 00000000:00 0[堆栈] 7fff18d0c000-7fff18d0d000 r-xp 00000000:00 0[vdso]
ffffffffff600000-FFFFFFFF601000 r-xp 00000000:00[vsyscall]我认为答案与中断处理更相关。中断处理程序地址在硬件中设置。在英特尔8086中,在中断处理程序代码和相应的中断处理例程上有一个直接转换表。也许,这是由一些组合电路完成的,因此,为了保持前向兼容性,将它们放在内存的开头比放在末尾更明智,以防止每次更改。因此,执行开始地址将位于内存的另一端。此外,有必要在该块中包含足够的代码,以加载内存段程序和跳转指令,从而切换以从该代码地址执行代码

你在这里说的是什么系统?我没有任何可靠的来源,但我可以做一个有保留的猜测。历史上,许多处理器,特别是8位处理器,都有被调用的功能,这意味着地址0x00-0xFF处的内存单元具有指令支持t