ряд вопросов по FASM

Assembler programming questions
  • scuter wrote:вроди бы всё просто пишешь формат и компилтся тот файл который нужен,
    но оказывается что всё савсем не так, эта директива меняет всю структуру построения программы
    А ты как хотел? :) Форматы тем и отличаются, что у них различная структура секций.
    scuter wrote:только вот как пользовать эти сегменты ?
    как сегменты распределюутся по процессору?
    для чего они нужны?
    какие у них ограничения?
    Сегменты - для удобства программистов. Например, может быть сегмент кода и сегмент данных. В сегменте данных хранятся исключительно данные, их можно считывать и записывать, но передавать управление на код из сегмента данных нельзя. А в сегмент кода наоборот, нельзя записывать данные, можно только читать. Использовать их надо с умом, держать сначала мануал, где расписано, как использовать сегменты для того или иного формата программ. Если ты пишешь для Колибри, тебе не нужно использовать сегменты. Если ты пишешь для Linux - то нужен формат ELF, для Windows - PE. В процессоре никаких сегментов нет, сегменты - они в памяти.
    scuter wrote:следующий вопрос по дерективе org
    что это за директива, что она делает, почему разные значения этой директивы формируют разнае форматы файлов
    что самое интересно если поставить org 100h и запустит .com программу с dos(именно dos не MS-DOS)
    то можете забыть про сегментные регистры вообще они нахрен не работают
    Представь, что ты программируешь в машинных кодах/на ассемблере. Ты пишешь команду jmp 0000. Эта команда - безусловного перехода на другую команду, записанную в памяти по адресу 0000. Когда ты создаешь в ассемблере метку, а потом делаешь jmp имя_метки, то ассемблер заменяет имя_метки на фактический адрес в памяти команды после метки. Если ты хочешь, чтобы твоя программа записывалась в память не с адреса 0, а с адреса, допустим, 100h, то ты делаешь org 100h и все метки рассчитываются не от 0, а от 100h. Кстати, в формате com компилятор fasm по умолчанию считает org 100h. Сегментные регистры, разумеется, не работают.
    scuter wrote:директивы use16 use32 use64
    что эти дерективы делают на сколько мне известно
    команды 32 это те же самые комманды что и 16 только дополненые
    комманды 64 это уже другие команды
    Мха. Эти директивы определяют, какой код будет получаться - 16-битный, 32-битный или 64-битный. Мнемоники команд в общем и целом одинаковые, а команды сами разные. Сравни
    mov ax, 10
    mov eax, 10
    mov rax, 10
    В режиме use16 вторая и третья команды не скомпилируются. В режиме use32 у первой команды, скорее всего, код операции будет не такой, как у той же команды в режиме use16 (хотя тут я не уверен).

    Вообще я советую тебе:
    а) Взять книжку по ассемблеру хорошую. Сначала что-то простое (блин, забыл фамилию автора хорошего учебника), потом - Юрова
    б) Параллельно с пунктом а скачать эмулятор УМПК-80 (да-да, восьмибитного процессора) и хорошенько разобраться с тем, как вообще работает процессор. Сделать на этом эмуляторе (он с компилятором ассемблера) несколько несложных программ - CRC-16, например.
  • Если точнее то use16, use32, use64 это режимы адресации и пример с mov не совсем из той оперы.

    scuter
    Чтобы получше понять, кроме книжек и документации стоит поставить дизассемблер (для dos и win лучше IDA) и по изучать, что будет на выходе в том или ином случае.
  • Хм, точно. Очевидное в голову не пришло почему-то.

    Кстати, в том же УМПК есть и дизассемблер.
  • Mario wrote:Если точнее то use16, use32, use64 это режимы адресации и пример с mov не совсем из той оперы.
    use16,32,64 -- это НЕ режимы адресации, а разрядность, для которой производится генерация кода. Например, одна и та же последовательность байтов в 16-разрядном режиме процессора может быть воспринята как команда MOV AX, 10, а в 32- и 64-разрядном -- как MOV EAX, 10. Чтобы в 16-разрядном режиме загрузить регистр EAX, а 32/64-разрядном -- AX, необходимо добавить в эту последовательность байтов префикс изменения размера операнда. Что же касается команды MOV RAX, 10, то для неё необходим префикс REX, который формируется транслятором только для 64-разрядного режима (в 16- и 32-разрядном режимах получить доступ к 64-разрядным регистрам невозможно).

    Режимы же адресации -- это совершенно другое. Применительно к архитектуре IA-32 обычно выделяют следующие режимы адресации:

    * неявная (когда все операнды, участвующие в операции, подразумеваются на основе кода самой операции; примеры -- все строковые команды вроде MOVS, STOS и т.д.);
    * регистровая (операнд находится в регистре; например, INC EAX);
    * косвенная (в регистре находится адрес операнда; например, INC DWORD PTR [EAX] -- как в синтаксисе FASM, я не знаю, поскольку им не пользовался);
    * прямая (в команде задан адрес операнда в явном виде; например, INC DWORD PTR 1234h, где 1234h -- этот самый адрес);
    * индексная (адресом операнда является сумма нескольких компонентов -- содержимого одного или двух регистров, один из которых может быть отмасштабирован, и отклонения (displacement); например, INC DWORD PTR 1234h [EBX]);
    * непосредственная (операндом является заданная в команде константа).

    Естественно, когда операндов несколько, для одного из них может использоваться один вид адресации, для второго -- другой (например, MOV AX, 10 -- первый операнд задан регистровой адресацией, второй -- непосредственной).
  • SoUrcerer wrote: Вообще я советую тебе:
    а) Взять книжку по ассемблеру хорошую. Сначала что-то простое (блин, забыл фамилию автора хорошего учебника), потом - Юрова
    б) Параллельно с пунктом а скачать эмулятор УМПК-80 (да-да, восьмибитного процессора) и хорошенько разобраться с тем, как вообще работает процессор. Сделать на этом эмуляторе (он с компилятором ассемблера) несколько несложных программ - CRC-16, например.
    чесно говоря уже просмотрел 15 мануалов от intel по 860 страниц
    различные учебники Калашникова Юрова и т.д.

    таким образом пришло понимание

    сталкнулся с рядом проблем, пилками в колесе, глючных кодов и т.п.

    MASM просто не запускался из-за проектных файлов
    TASM заглючил и в конце концов запросил лицензию и окончательно отключился

    и остался FASM единственный компиль который работает

    дизассемблер поставил с самого начала при чем штук 7
    такие перлы они мне выдавали что уму не постежимо

    и в конце концов запустил всё таки коды в базовом(BIOS DOS) режиме

    и единственные затруднения которые сейчас у меня это

    вывод кодировки EOM 866
    организация данных в коде и определится с форматом файла
    для чего нужен EOM думаю обьеснять не надо

    организация данных в коде
    к примеру получение информации о VESA режиме
    накопал такую структуру

    Code: Select all

    struc VESAInfoBlock
    {
    VESASignature     db 'VESA' ;VESA сигнатура
    VESAVersion       dw ? ;версия VESA (0100h, 0102h или 0200h)
    OemStringPtr      dd ? ;указатель на строку с именем производителя (заканчивается "0")
    Capabilities      db 4 dup (?) ;флаги графических возможностей
    VideoModePtr      dd ? ;указатель на список видеорежимов
    TotalMemory       dw ? ;размер видеопамяти в 64-Кбайт блоках;
    OemSoftwareRev    dw? ;номер версии реализации VBE
    OemVendorNamePtr  dd? ;указатель на строку с именем поставщика
    OemProductNamePtr dd? ;указатель на строку с названием продукта
    OemProductRevPtr  dd? ;указатель на строку с версией продукта
    Reserved          db 222 dup (?) ;зарезервировано; область расширения блока
    OemData           db 256 dup (?) ;область данных для строк производителя
    }
    
    и вот как этой структурой пользоваться, директива virtual не помогает

    и там ещё много примеров такого типа

    с форматом файла савсем ничего не могу понять
    в данный момент пользую org 7C00h и компилится файл в формате bin
  • SII
    Хорошо, не режим а разрядность адресации. Однако:
    Например, одна и та же последовательность байтов в 16-разрядном режиме процессора может быть воспринята как команда MOV AX, 10, а в 32- и 64-разрядном -- как MOV EAX, 10. Чтобы в 16-разрядном режиме загрузить регистр EAX, а 32/64-разрядном -- AX, необходимо добавить в эту последовательность байтов префикс изменения размера операнда. Что же касается команды MOV RAX, 10, то для неё необходим префикс REX, который формируется транслятором только для 64-разрядного режима (в 16- и 32-разрядном режимах получить доступ к 64-разрядным регистрам невозможно).
    опять таки не из той оперы. Человек рассматривал запись в исходном коде. А насчет твоих слов:
    Spoiler:

    Code: Select all

    use16
    ;--------------------------------------
    align 16
    	db 'm_al'
    ;--------------------------------------
    align 16
    	mov	al,10	;B0 0A
    ;--------------------------------------
    align 16
    	db 'm_ax'
    ;--------------------------------------
    align 16
    	mov	ax,10 	;B8 0A 00
    ;--------------------------------------
    align 16
    	db 'meax'
    ;--------------------------------------
    align 16
    	mov	eax,10	;66 B8 0A 00 00 00
    ;-----------------------------------------------------------------------------
    use32
    ;--------------------------------------
    align 16
    	db 'm_al'
    ;--------------------------------------
    align 16
    	mov	al,10	;B0 0A
    ;--------------------------------------
    align 16
    	db 'm_ax'
    ;--------------------------------------
    align 16
    	mov	ax,10	;66 B8 0A 00
    ;--------------------------------------
    align 16
    	db 'meax'
    ;--------------------------------------
    align 16
    	mov	eax,10	;B8 0A 00 00 00
    ;-----------------------------------------------------------------------------
  • org 7с00 - это загрузчик с дискеты вроде бы :)
    Мануал от fasm - подробнейшим образом раскрывает особенности fasm как ассемблера, в том числе структуры и прочее.
    Но я все же советую для начала не использовать fasm, а попрограммировать на более простом (по сравнению с x86) ассемблере. Скажу по секрету: ты еще не познал дзен.
  • scuter
    Так не катит?

    Code: Select all

    align 4
    vesa_block VESAInfoBlock
    ;-----------------------------------------------------------------------------
    mov eax, [vesa_block.VESASignature]
    
    или
    
    mov eax, vesa_block.VESASignature
    cmp [eax],byte 'V'
    и не забываем про нужные include
  • Mario wrote:scuter
    Так не катит?

    Code: Select all

    align 4
    vesa_block VESAInfoBlock
    ;-----------------------------------------------------------------------------
    mov eax, [vesa_block.VESASignature]
    
    или
    
    mov eax, vesa_block.VESASignature
    cmp [eax],byte 'V'
    и не забываем про нужные include
    не четно говоря не пробовал
    кстати что означает align 4
  • scuter wrote:к примеру получение информации о VESA режиме
    накопал такую структуру

    Code: Select all

    struc VESAInfoBlock
    {
    VESASignature     db 'VESA' ;VESA сигнатура
    ...
    }
    
    и вот как этой структурой пользоваться, директива virtual не помогает
    Открываем документацию по FASM (кстати, а почему бы было не прочитать её до создания темы?) и видим, что формат объявления структуры немного другой: кто самый внимательный, тот замечает точки в начале имён членов.

    Для дальнейшего развития, можно из стандартной поставки FASM посмотреть в файл struct.inc (он есть, кстати, и на SVN в несчётном количестве экземпляров, вместе с кучей примеров его использования).
    in code we trust
  • mike.dld wrote: Открываем документацию по FASM (кстати, а почему бы было не прочитать её до создания темы?) и видим, что формат объявления структуры немного другой: кто самый внимательный, тот замечает точки в начале имён членов.

    Для дальнейшего развития, можно из стандартной поставки FASM посмотреть в файл struct.inc (он есть, кстати, и на SVN в несчётном количестве экземпляров, вместе с кучей примеров его использования).
    Открываю GDI32.INC и волшебным образом вижу:
    Spoiler:

    Code: Select all

    ; GDI32.DLL structures and constants
    
    struct SIZE
      cx dd ?
      cy dd ?
    ends
    
    struct BITMAP
      bmType       dd ?
      bmWidth      dd ?
      bmHeight     dd ?
      bmWidthBytes dd ?
      bmPlanes     dw ?
      bmBitsPixel  dw ?
      bmBits       dd ?
    ends
    
    struct BITMAPCOREHEADER
      bcSize     dd ?
      bcWidth    dw ?
      bcHeight   dw ?
      bcPlanes   dw ?
      bcBitCount dw ?
    ends
    
    ...
    
    Что это? Чудо Господне? :wink:

    Конечно это без скобок.

    З.Ы. Очень рад, что ты оказывается умеешь иногда разговаривать на русском языке не только в личку.
  • scuter wrote:кстати что означает align 4
    Выравнивание ниже стоящего кода на границу кратную 4 - м байтам. Если ниже стоящий код вдруг начинается с адреса кратного 4 - м, то эта строка ничего не делает. Иначе дописывает нужное число операций nop (которые ничего не делают). Во многих случаях такое выравнивание ускоряет работу программы, потому как процессор быстрее работает с адресами кратными 4 - м.
  • mike.dld wrote: Открываем документацию по FASM (кстати, а почему бы было не прочитать её до создания темы?) и видим, что формат объявления структуры немного другой: кто самый внимательный, тот замечает точки в начале имён членов.

    Для дальнейшего развития, можно из стандартной поставки FASM посмотреть в файл struct.inc (он есть, кстати, и на SVN в несчётном количестве экземпляров, вместе с кучей примеров его использования).
    вот только не надо тыкать носом в документацию,
    так обычно делают дибилы (они говорят читай мануал или google в помощ)

    если бы там всё было написано нормальным доступным языком, я бы и не спрашивал.
  • scuter wrote:
    mike.dld wrote: Открываем документацию по FASM (кстати, а почему бы было не прочитать её до создания темы?) и видим, что формат объявления структуры немного другой: кто самый внимательный, тот замечает точки в начале имён членов.

    Для дальнейшего развития, можно из стандартной поставки FASM посмотреть в файл struct.inc (он есть, кстати, и на SVN в несчётном количестве экземпляров, вместе с кучей примеров его использования).
    вот только не надо тыкать носом в документацию,
    так обычно делают дибилы (они говорят читай мануал или google в помощ)

    если бы там всё было написано нормальным доступным языком, я бы и не спрашивал.
    Ты бы не спрашивал, если бы читал. Причем если читал бы литературу в нужном порядке. Если ты первоклассника заставишь читать учебник по квантовой механике, он мало что из этого учебника для себя откроет. Понимаешь, о чем я?
    В процессе работы над Колибри у меня тоже возникает немало вопросов. Но, прежде чем задавать вопросы на форуме, я стараюсь всеми силами разобраться самостоятельно: читаю книжки, руководства пользователей, ищу в google, читаю исходный код других программ, где используются подобные решения. Сразу никогда ничего не работает. Одну программу приходится перекомпилировать десятки и сотни раз. Толково заданный вопрос - это уже половина ответа. Факт.
  • Who is online

    Users browsing this forum: No registered users and 3 guests