Memory management 如何指定应使用哪个段寄存器(x86)

Memory management 如何指定应使用哪个段寄存器(x86),memory-management,x86,x86-64,addressing-mode,memory-segmentation,Memory Management,X86,X86 64,Addressing Mode,Memory Segmentation,这里有一个函数: void func(char *ptr) { *ptr = 42; } 下面是gcc-s function.c的输出(cut): func: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movq %rdi,

这里有一个函数:

void    func(char *ptr)
{
    *ptr = 42;
}
下面是gcc-s function.c的输出(cut):

func:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rax
    movb    $42, (%rax)
    nop
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
我可以将该函数用作:

func(malloc(1));
或作为:

char local_var;
func(&local_var);
问题是处理器如何确定应使用哪个段寄存器将此指令中的有效地址转换为虚拟地址(可能是DS,也可能是SS)


我有一个x86_64进程。

默认段是DS;这就是处理器在您的示例中使用的内容

在64位模式下,使用哪个段无关紧要,因为段基始终为0,并且忽略权限。(有一两个细微的差别,我在这里不再赘述。)

在32位模式下,大多数操作系统将所有段的基数设置为0,并将其权限设置为相同,因此这也没关系


在重要的代码中(特别是需要使用64KB以上内存的16位代码),代码必须使用远指针,其中包括作为指针值一部分的段选择器。软件必须将选择器加载到段寄存器中才能执行内存访问

所以,据我所知,错误“分段错误”并不意味着什么,现代操作系统实际上没有分段?为什么有很多关于habr的文章描述不同的段(文本(代码)段、数据、堆栈、堆)呢?段错误和段寄存器是不相关的。他们碰巧用了同一个词,但意思不同。(大多数处理器没有段寄存器,但所有Unix系统都调用访问冲突段错误。)软件定义的段(文本、数据、bss等)也与硬件段和段寄存器无关。@RaymondChen您能澄清一下它们之间的区别吗?如果现代操作系统不使用段寄存器,那么操作系统是否还有另一种逻辑划分内存的方法?Linux如何用代码保护内存不被更改?现代操作系统使用分页来保护内存。
movb    $42, (%rax)