связка Visual C++ 2017 с MASM

Тема в разделе "WASM.BEGINNERS", создана пользователем kol1978, 18 фев 2025 в 07:20.

  1. kol1978

    kol1978 New Member

    Публикаций:
    0
    Регистрация:
    Воскресенье
    Сообщения:
    24
     
  2. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    500
    Не, то что бывают 16-битная и 32-битная адресации это то факт который невозможно пропустить.
    Я пропустил что именно делает префикс (далее цитата из Intel Manual):
    Что не просто там обрезает результат до 16 бит адреса, а действительно именно возвращает дешифровку modR/M к 16-битной форме. Да, так и есть. Такая редкость, что никогда не акцентировал я на этом внимания.
     
  3. kol1978

    kol1978 New Member

    Публикаций:
    0
    Регистрация:
    Воскресенье
    Сообщения:
    24
    "информацию о коде операции;" - во! тут еще термин добавился - "код операции" , а! эта какая часть опкода!?(риторически)
    --- Сообщение объединено, 19 фев 2025 в 10:12 ---
    Присоединяюсь...надо бы ссылку на инфу+ наверное точно можно найти в загрузчике ядра там где включается защищённый режим... и! вопрос к знатокам - это можно найти в юзер-коде? ("Префикс переопределения размера адреса (67H) позволяет программам переключаться между 16- и 32-битной адресацией."):vinsent:
     
  4. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    500
    Поднятый тобой вопрос довольно сложный. Надеюсь ты уже понял как дела обстоят в рядовых машинных инструкциях - нельзя сослаться на адрес отстоящий либо от начала памяти на +-2Гб либо от текущего IP на те же смещения.
    Компиляторы хитрят и применяют техники отлаженные на процессорах архитектур RISC где RIP это навязанный факт в силу похожих причин с тем, что происходит в i86_64.
    Пока размеры экзешников не превышают 2Гб это всё может вообще никак себя не проявлять и просто работать.
    Но на самом деле про это уже давно думают. Например компиляторы обязательно будут делать доступ к глобалкам через RIP. Но если нужно загрузить адрес чего-то, что потенциально может быть где угодно в 64-битном адресном пространстве, то простейший трюк такой:
    Код (Text):
    1.  
    2. ; где то не дальше, чем 2Гб
    3. symbol: dq address64
    4. ...
    5. mov rsi, symbol[rip]
    6.  
    Немного еще разряжается обстановка тем, что таблицы импорта DLL работают по схожему принципу, поэтому тоже достаточно чтобы текущий юнит компиляции дотягивался до своих таблиц через RIP и дело в шляпе.
    У компиляторов уже есть опции такие: https://eli.thegreenplace.net/2012/01/03/understanding-the-x64-code-models
    Эдакое возвращение витка истории к large/small/tiny из 8086:
    На ассемблере ты можешь просто не понимать что закладываешь такие грабли и всего лишь. Но пока <2Gb работать будет до поры до времени пока какой нибудь очередной механизм перестановки адресов кода для предотвращения атак по известным адресам не решит переставить образ за пределы 2Gb (не думаю, что MS сейчас такое может делать как раз из-за существования проблем таких, да и в будущем скорее всего не будет тоже делать если EXE не помечен маркером "я умею работать выше 2Gb").
     
  5. MaKsIm

    MaKsIm Active Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    138
    По той ссылке все есть про кодирование инструкций x86. Только надо поискать на страницах.

    Только это описание устарело. Там нету ничего про long mode

    Но вы сначала разберитесь в 16 и 32 битах. long mode это просто расширенные 32-бита до 64-х
     
  6. kol1978

    kol1978 New Member

    Публикаций:
    0
    Регистрация:
    Воскресенье
    Сообщения:
    24
    А давайте вы сами сначала разберитесь во всем, и только потом указывайте мне что делать...
    --- Сообщение объединено, 19 фев 2025 в 11:32 ---
    "Надеюсь ты уже понял как дела обстоят в рядовых машинных инструкциях - нельзя сослаться на адрес отстоящий либо от начала памяти на +-2Гб " - а я надеюсь что ты понял в чем разница между адресацией в защищенном режиме и другой...потому что это:
    Код (Text):
    1. ; где то не дальше, чем 2Гб
    2. symbol: dq address64
    3. ...
    4. mov rsi, symbol[rip]
    просто "глюк"(а не трюк) , просто поместить переменную в регистр...не более... либо плиз - полный текст кода для запуска!
     
  7. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    500
    Ну дык давно бы уже сам попробовал написать кодес где между переменной и операцией её загрузки лежит больше 2Гб чего либо.
    У меня нет масмов под рукой, а компиляторы стремятся сами выправлять такие случаи миксуя загрузки через промежуточные времянки которые линкеру нет труда заполнить. По вот той самой схеме.
    P.S.
    И еще рекомендую дизасм смотреть того, что собираешь потому что в какие именно конкретно инструкции с какими адресациями ассемблер разворачивает код тоже вопрос - наткнулся сейчас на высказываение в гугле, что MASM подставляет [rip] неявно за программиста по умолчанию.
     
  8. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.898
    kol1978, а хамить не стоит...
     
  9. kol1978

    kol1978 New Member

    Публикаций:
    0
    Регистрация:
    Воскресенье
    Сообщения:
    24
    Ну как бы оно такое...пользуйтесь:
    $ sudo apt-get install nasm

    и! вопрос к вопросу на вопрос - режим ЦП при том? и если есть ограничение то - это ограничение ассемблера или ЦП? в общем затея так себе... И! если у вас нет ничего "под рукой" на каком основании вы что то пишите ? претендуете на правду?
     
  10. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    500
    Пока ты не вспонишь что я тут писал и не восстановишь таким образом основания на которых я это писал (да, придётся напрячь память) я потерял интерес что либо еще объяснять.
    Просто как о стенку горох, ну такое.
    Если хочешь продолжения диалога со мной найди те 3 (три) источника из которых я черпал сведения и приведи полные ссылки на них здесь. До того момента оревуар, я подозреваю ты то ли не хочешь воспринимать информацию, то ли не можешь, то ли еще не готов, х/з. Но в твоих интересах давно уже было эти источники информации начать держать под рукой тоже.
     
    Последнее редактирование: 20 фев 2025 в 04:32
  11. kol1978

    kol1978 New Member

    Публикаций:
    0
    Регистрация:
    Воскресенье
    Сообщения:
    24
    не могу вспомнить где так отвечал...удалили уже?
    Суть в том что что бы спрашивать об ограничениях в адресации необходимо уточнить для какого режима это применяется: для реального или защищенного (архитектура по умолчанию 86-64), но так как насколько мне известно режима четыре - есть режим ядра и пользовательский (для ОС linux) т.е. привилегированный и непривилегированный -
    . А рассмотрение для каждого режима/уровня ограничения по адресации в контексте данного поста в разделе для новичков - то оно "такое" . Поэтому суть ответа: дайте четкое определение того что хотите этим(этим указанием) сказать/выяснить.
    --- Сообщение объединено, 20 фев 2025 в 04:43 ---
    в продолжение: это по моему ваш код
    Код (Text):
    1. #include <stdio.h>
    2. #pragma code_seg(".shell")
    3. __declspec(allocate(".shell"))
    4.  
    5. static const unsigned char s_readCs[]
    6. {
    7.     0x66, 0x8C, 0xC8, // mov ax, cs
    8.     0xC3              // ret
    9. };
    10. typedef unsigned short (*ReadCs)();
    11. unsigned short _asm_read_cs()
    12. {
    13.     return ((ReadCs)&s_readCs[0])();
    14. }
    15.  
    16. int main()
    17. {
    18.     printf("0x%X\n", _asm_read_cs());
    19.     return 0;
    20. }
    - можете дать пример такого кода для компиляции gcc в linux? это как раз в тему : поразбираться с сегментами данных и кода...
    --- Сообщение объединено, 20 фев 2025 в 05:52 ---
    Вот твои "три строчки" по поводу которых имеются "недопонимания" и не только у меня...:
    На вопрос о синтаксисе и ассемблеры не захотел отвечать (mov eax, [cx+$0010] - нет такого синтаксиса или вообще это не верно)... и придумал новый вопрос про 2 гигабайта...
    Вот про два гигабайта мой ответ: не знаю в чем причина ограничения 2Гб - размер бинарного ф.? размер сегмента(оы)? разрядность адресуемого кода...(не знаю как точно сформулировать коротко)?
    Код (Text):
    1. ----------------nano hello.s
    2. .text                      #расположение исполняемого кода
    3.      .globl main;
    4. main:                      #точка входа
    5.         endbr64
    6.         pushq   %rbp
    7.         movq    %rsp, %rbp
    8.         movl    $15, %edx
    9.         leaq    message(%rip), %rax
    10.         movq    %rax, %rsi
    11.         movl    $1, %edi
    12.         call    write
    13.         movl    $0, %edi
    14.         call    _exit
    15.         . = main + 1147483648      #перемещение из позиции гигабайта
    16. .data
    17. message:
    18.         .string "Hello, world!\n"
    19.  
    20. -------------------------------------------
    компиляция : gcc -static -fpie -Os -m64 hello.s -o hello
    файл получается: -rwxrwxr-x 1 kol kol 1147498096 фев 20 10:37 hello
    но если 2гига то нет:
     
  12. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    500
    Все ответы уже были, например:
    upload_2025-2-20_11-2-48.png

    Чтобы понять что ты хочешь выразить в синтаксисе ассемблера очень важно понимать, а что вообще должно в результате получаться. Что за машинный код будет сгенерирован. Вот я всегда тут говорил про то какой машинный код может быть исполнен процессорами x86. Что он из себя представляет.
    С ассемблерами на самом деле интересная штука - например в RISC-ах вообще псевдоинструкции сплошь и рядом - для краткости синтаксиса там зачастую пишешь одну мнемонику, а под капотом ассемблер генерит несколько инструкций с совсем другими мнемониками. Ну физически нет 32-битного mov rx, immediate, поэтому каждый изгаляется как может.
    Судя по тому что я вчера в гугле заметил MASM может вменить [rip] к mov eax, label даже если программист не написал его явно. Поэтому тоже вопрос - надёжнее всего разглядывать потом дизасм собранного.
    В общем все ответы уже были выше, ты просто невнимательно что ли читаешь или не знаешь как задать правильный вопрос.
     
  13. MaKsIm

    MaKsIm Active Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    138
    Те вы даже не понимаете, то в 32 битный непосредственный адрес в команде (а больше 32 бит он быть не может) просто физически не помещаются смещения больше 2Гб в обе стороны (32-битное число со знаком это числа в диапазоне [-2Гб .. 2Гб-1]). И если это вам так важно, то это ограничения системы команд процессора.
    --- Сообщение объединено, 20 фев 2025 в 12:59 ---
    Достаточно было просто внимательно прочитать информацию по ссылке, которую я вам дал. Там есть все таблицы дешифрации байтов modr/m и sib, для 32-битного режима и 16-битного. В 64-битном режиме таблица расшифровки modr/m и sib совпадает с таблицей для 32-бит, но там еще добавляется действия префиксов rex, а регистры заменяются на 64-битные при его использовании.

    Хотя у вас конкретная каша в голове. Вы пишите программу только для пользовательского режима. При чем тут системные уровни защиты,
     
  14. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    514
    допустим я купил себе БУ супер-мини-компьютер
    128 CPU
    10 TB RAM
    как работать с кусками аллоцированной памяти больше 2/4 ГБ?
     
  15. Ahimov

    Ahimov Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    86
    kol1978

    Какую кодировку использовать 16/32(modrm) цпу определяет из кодового сегмента, который описывается ldt/gdt и там есть маркер разрядности :)
     
  16. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    500
    Так проблемы работать с памятью нет. Есть проблема как сразу за одну инструкцию загрузить в регистр 128-битное значение если нет 128-битных immediate. И в этом может помочь как пара инструкций с 64-битным immediate так и одна инструкция с 24-битным offset относительно IP.
     
  17. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.479
    Адрес:
    Россия, Нижний Новгород
    То же самое, что для msvc, только используем gcc'шный атрибут __attribute__((section(".text.shell"))), чтобы положить шелл в секцию кода:
    Код (C++):
    1. #include <cstdio>
    2.  
    3. __attribute__((section(".text.shell")))
    4. static const unsigned char s_readCs[]
    5. {
    6.     0x66, 0x8C, 0xC8, // mov ax, cs
    7.     0xC3              // ret
    8. };
    9.  
    10. typedef unsigned short (*ReadCs)();
    11.  
    12. unsigned short _asm_read_cs()
    13. {
    14.     return ((ReadCs)&s_readCs[0])();
    15. }
    16.  
    17. int main()
    18. {
    19.     printf("0x%X\n", _asm_read_cs());
    20.     return 0;
    21. }
    Код (Bash):
    1. $ g++ ./main.cpp -o ./main && ./main
    2. 0x33
    Но в gcc не нужно использовать шеллы, т.к. в нём есть встроенный инлайн-ассемблер.
    То же самое можно сделать через него - в прошлой теме писал пример:
    Код (C++):
    1. inline unsigned short _asm_read_cs()
    2. {
    3.     unsigned short result = 0;
    4.     __asm__ volatile ("mov %%cs, %[result]" : [result] "=r" (result));
    5.     return result;
    6. }
     
    kol1978 нравится это.
  18. kol1978

    kol1978 New Member

    Публикаций:
    0
    Регистрация:
    Воскресенье
    Сообщения:
    24
    Класс!!!!!!!!!!!!!!!!! Работает!!!!!!!!! Ура! есть польза от сайта!!! огромное спасибо! ps буду дизасемблить и смотреть...
    --- Сообщение объединено, 21 фев 2025 в 07:20 ---
    Ладно! тогда сразу с места:
    Много result __asm__ volatile ("mov %%cs, %[result]" : [result] "=r" (result)); это сбивает с толку..
    предлагаю хотя бы один result убрать : __asm__ volatile ("mov %%cs, %0" : "=r" (result));

    g++ -S main.cpp :
    Код (Text):
    1. kol@kol:~/ASM/code16$ cat main.s
    2.     .file    "main.cpp"
    3.     .text
    4.     .section    .text.shell,"a"
    5.     .type    _ZL8s_readCs, @object
    6.     .size    _ZL8s_readCs, 4
    7. _ZL8s_readCs:
    8.     .ascii    "f\214\310\303"
    9.     .text
    10.     .globl    _Z12_asm_read_csv
    11.     .type    _Z12_asm_read_csv, @function
    12. _Z12_asm_read_csv:
    13. .LFB0:
    14.     .cfi_startproc
    15.     endbr64
    16.     pushq    %rbp
    17.     .cfi_def_cfa_offset 16
    18.     .cfi_offset 6, -16
    19.     movq    %rsp, %rbp
    20.     .cfi_def_cfa_register 6
    21.     leaq    _ZL8s_readCs(%rip), %rax
    22.     call    *%rax
    23.     popq    %rbp
    24.     .cfi_def_cfa 7, 8
    25.     ret
    26.     .cfi_endproc
    27. .LFE0:
    28.     .size    _Z12_asm_read_csv, .-_Z12_asm_read_csv
    29.     .section    .rodata
    30. .LC0:
    31.     .string    "0x%X\n"
    32.     .text
    33.     .globl    main
    34.     .type    main, @function
    35. main:
    36. .LFB1:
    37.     .cfi_startproc
    38.     endbr64
    39.     pushq    %rbp
    40.     .cfi_def_cfa_offset 16
    41.     .cfi_offset 6, -16
    42.     movq    %rsp, %rbp
    43.     .cfi_def_cfa_register 6
    44.     call    _Z12_asm_read_csv
    45.     movzwl    %ax, %eax
    46.     movl    %eax, %esi
    47.     leaq    .LC0(%rip), %rax
    48.     movq    %rax, %rdi
    49.     movl    $0, %eax
    50.     call    printf@PLT
    51.     movl    $0, %eax
    52.     popq    %rbp
    53.     .cfi_def_cfa 7, 8
    54.     ret
    55.     .cfi_endproc
    56. .LFE1:
    57.     .size    main, .-main
    58.     .ident    "GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0"
    59.     .section    .note.GNU-stack,"",@progbits
    60.     .section    .note.gnu.property,"a"
    61.     .align 8
    62.     .long    1f - 0f
    63.     .long    4f - 1f
    64.     .long    5
    65. 0:
    66.     .string    "GNU"
    67. 1:
    68.     .align 8
    69.     .long    0xc0000002
    70.     .long    3f - 2f
    71. 2:
    72.     .long    0x3
    73. 3:
    74.     .align 8
    75. 4:
    76.  
    вот наш массив в 4 байта :
    .size _ZL8s_readCs, 4
    _ZL8s_readCs:
    .ascii "f\214\310\303"
    это вот это :
    0x66, 0x8C, 0xC8, // mov ax, cs
    0xC3 // ret
    При этом там есть "указание" - .ascii, но! вот эта "гавнофункция" - _Z12_asm_read_csv тупо грузить адрес в аккумулятор и передаёт на него управление:
    leaq _ZL8s_readCs(%rip), %rax
    call *%rax
    Почему то был уверен что это так просто сделать не возможно...!
    А возможно такое сделать с указанием конкретного мести в памяти (адреса) пусть с применением вызова линковщика как то в таком стиле:
    Код (Text):
    1. ----------nano test.c
    2.  
    3. __asm__(".code16\n");
    4. __asm__("jmpl $0x0000, $main\n");
    5.  
    6. void main() {
    7. }
    8.  
    9. ---------------------------nano test.ld
    10. ENTRY(main);
    11. SECTIONS
    12. {
    13.     . = 0xHHHH;
    14.     .text : AT(0xHHHH)
    15.     {
    16.         *(.text);
    17.     }
    18.     .sig : AT(0xHHHH)
    19.     {
    20.         SHORT(0xHHHH);
    21.     }
    22. }
    23. ------------------------
    24. gcc -c -g -Os  test.c -o test.o
    25. ld -static -Ttest.ld  -o test.elf test.o
    ???
    --- Сообщение объединено, 21 фев 2025 в 07:27 ---
    А как работать с ф. более 2 гигов знаете? скажем в примере
    Код (Text):
    1.    . = main + 1147483648      #перемещение из позиции гигабайта
    заменить число на 2147483648 и скомпилировать и запустить? Вопрос в плане : почему для 64 разрядной системы и ЦП ограничение как для 32 разрядной? и из чего складывается ограничение в 4 гига для 64разрядной - тоже?
    --- Сообщение объединено, 21 фев 2025 в 07:36 ---
    Ну то есть по сути и коротко: вы хотите сказать что ЦП 64 разряда на самом деле не 64 а 32 и у него просто имеются 64 разрядные регистры (регистры общего назначения: Шестнадцать 64-разрядных регистров RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, R8, R9, R10, R11, R12, R13, R14 и R15) и только это делает его "шестидесяти четырёх разрядным". И! условно - шина адреса 32 разрядная, от этого ограничение в 2 гига. - Так?
     
  19. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    500
    Давайте рассмотрим такой кодес на шланге:
    Код (Text):
    1.  
    2. extern int x;
    3. int func()
    4. {
    5.     return x + 1;
    6. }
    7.  
    Т.е. где то вовне текущего модуля компиляции существует переменная x и мы не знаем где именно - близко к RIP или далеко - что делать?
    Опции компилятора -O3 -std=c++23
    Получаем:
    Код (Text):
    1.  
    2. func():
    3.         mov     rax, qword ptr [rip + x@GOTPCREL]
    4.         mov     eax, dword ptr [rax]
    5.         inc     eax
    6.         ret
    7.  
    Аха. Что мы видим - переменная не грузится непосредственно в регистр, а через RIP грузится её адрес, а из адреса уже выходит компилятор на содержимое.
    Что такое x@GOTPCREL? А это таблица внутри текущего модуля компиляции, т.е. гарантированно достаточно близка к текущему коду не дальше, чем 2Гб и в ней компилятор попросит линкер отложить полный 64-битный адрес переменной.
    Логично? Логично.
    Но что если изменить опции копиляции на -O3 -std=c++23 -mcmodel=large ?
    Давайте попробуем и получится немного более громоздкий кодес:
    Код (Text):
    1.  
    2. func():
    3. .L0$pb:
    4.         lea     rax, [rip + .L0$pb]
    5.         movabs  rcx, offset _GLOBAL_OFFSET_TABLE_-.L0$pb
    6.         add     rcx, rax
    7.         movabs  rax, offset x@GOT
    8.         mov     rax, qword ptr [rcx + rax]
    9.         mov     eax, dword ptr [rax]
    10.         inc     eax
    11.         ret
    12.  
    Что произошло? Теперь компилятор не уверен в том, что таблица полных адресов достижима от текущего IP и начинает делать приседания чтобы гарантированно достичь её по полному 64-битному адресу.
    Но при этом строго следует идиоме PIC (position independent code) которая для x86_64 является штукой дефолтной.
    Сперва он высчитывает полный 64-битный оффсет от текущего кода до GOT, а потом уже извлекает из неё адрес переменной (pаметьте, что отсутствующий в классической мнемонике Intel movabs это как раз 64-битный mov immediate - эти 64-битные смещения уже приходится сперва загрузить в регистр, а потом уже складывать).

    Вот так с проблемой отсутствия 64-битных оффсетов справляется шланг. Причём заметьте - сложность решений во многом проистекает именно из-за PIC и тех моментов когда компиляторы стараются снизить количество "точек связывания". Руками на ассемблере можно было бы просто шлёпать movabs rax, OFFSET label и сразу переходить к mov rax, [rax].
     
    Последнее редактирование: 21 фев 2025 в 08:14
  20. kol1978

    kol1978 New Member

    Публикаций:
    0
    Регистрация:
    Воскресенье
    Сообщения:
    24
    Постепенно появляется уверенность что вы просто пытаетесь запутать ситуацию еще больше...: зачем (почему) применили -std=c++23? у вас есть такой компилятор...? почему не объяснили значение -mcmodel=large? на коков вопрос отвечаете сиим длинным монологом? зачем приплетаете сюда PIC (position independent code): приведите пример без оптимизации, с обычным стандартом и для флагов -no-pie и -fpie (так хоть может появиться надежда понять что вы пытаетесь объяснить)? "Потому что нету mov eax, [addr64] и ..." - это простой вопрос и должен быть простой ответ - почему нету?
    --- Сообщение объединено, 21 фев 2025 в 08:59 ---
    Видимо все же тема поста и "мой парадокс" имеет непосредственное отношение к ограничению 2гига... продолжим рассуждать:

    FAT32 не дает сделать файл больше 2Гб.
    На ext3 же вроде нет (у меня ext4 так что это точно не мой вариант...). На ext2 есть - абсолютно не мой вариант...
    Так вот, эта же 32-битная программа, запущенная на 64-битной системе, может выделить почти 4 GB памяти (на практике около 3.5 GB) - тут речь про 32-битная программа, а если компилировать gcc -m64 (64-битная программа - если это так) то какое тогда имеется ограничение и почему?
    Теоретически 64-разрядный процессор может адресовать до 16 эксабайт (16 млн терабайт) памяти.
    Однако допустимые в реализациях физические и математические адреса часто ограничены значениями 48 бит (256 терабайтов), реже — 52 или 56 битов.
    Рассматриваемая архитектура Intel 64 простое, но в то же время мощное обратно совместимое расширение устаревшей промышленной архитектуры x86.
    Она добавляет 64-битное адресное пространство (о каком пространстве адресов идёт речь: виртуальные? физические? логическо-мнимые...ЁПРСТ!?) и расширяет регистровые ресурсы для поддержки большей производительности перекомпилированных 64-битных программ (каким образом перекомпилировать в gcc что бы получить полноценый результат?).
    Архитектура обеспечивает поддержку устаревшего 16-битного и 32-битного кода приложений и операционных систем без их модификации или перекомпиляции.
    ------------------
    это добавляет парадоксальности (по моему):
    набор команд x86-64 поддерживает множество различных режимов адресации для доступа к операндам, хранящимся в памяти:
    mov rax,[rbx]
    mov rax,[rbx+16]
    mov rax,[r15*8+48]
    mov rax,[rbx+r15]
    mov rax,[rbx+r15+32]
    mov rax,[rbx+r15*8]
    mov rax,[rbx+r15*8+64]
    тогда нас интересует: mov rax,[Val] , где переменная Val каким то образом ограниченна...Если на размер файла в 2 Гб ограничение создаётся 32-битным целочисленным ограничением (2 147 483 647),
    которое является максимально возможным целым числом, которое может быть представлено 32 двоичными цифрами.
    Это ограничение преодолевается использованием расширения физического адреса (PAE) позволяет преодолеть этот барьер за счёт расширения адресов, используемых для представления сопоставлений между виртуальной и физической памятью.
    Просьба ответить на вопросы в русле данного рассуждения?
     
    Последнее редактирование: 21 фев 2025 в 09:05