Как указывается, какой сегментный регистр следует использовать (x86) - PullRequest
0 голосов
/ 23 марта 2020

Вот функция:

void    func(char *ptr)
{
    *ptr = 42;
}

Вот вывод (обрезка) функции g cc -S. c:

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)

movb    $42, (%rax)

У меня есть x86_64 pro c.

1 Ответ

1 голос
/ 23 марта 2020

Сегмент по умолчанию - DS; это то, что процессор использует в вашем примере.

В 64-битном режиме не имеет значения, какой сегмент используется, потому что база сегмента всегда равна 0, а разрешения игнорируются. (Есть одно или два незначительных отличия, которые я не буду go описывать здесь.)

В 32-разрядном режиме большинство ОС устанавливают для всех сегментов основание на 0 и устанавливают одинаковые разрешения. так что, опять же, это не имеет значения.

В коде, где это важно (особенно в 16-битном коде, который должен использовать более 64 КБ памяти), код должен использовать дальние указатели, которые включают селектор сегмента как часть значения указателя. Программное обеспечение должно загрузить селектор в регистр сегмента для доступа к памяти.

...