Задать вопрос
Ответы пользователя по тегу Assembler
  • Как происходит работа с short в asm?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    00000234: xori r16,r16,32768
    00000238: addi r16,r16,-32768

    Это классическое расширение знакового бита, в данном случае для 16-битного числа: если бит 15 был установлен (число отрицательное), то после xor он будет сброшен (т.е. он и все биты старше него станут нулями), а после addi бит 15 и все старше него станут единицами. Если бит 15 был сброшен (число неотрицательное), то после xor он будет установлен, а после addi -- сброшен опять.

    Подскажите пожалуйста смысл таких преобразований?

    Знаковое расширение -- это часть short right = acum & 65535;. Оно нужно для того, чтобы работать с загруженными в регистры значениями не задумываясь об исходной ширине их типа данных. Т.е. (short)-1 в 64-битном регистре будет представлен как 0xffffffffffffffff, а не как 0xffff.
    Ответ написан
    Комментировать
  • Есть ли программы анализа листинга на assembler?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Eсть программа на assembler без комментариев. Надо ее ускорить, изменив некоторые участки. Искать эти участки большая морока.

    Искать эти участки можно с помощью профилирования.
    Ответ написан
  • Как задать регистры стека ss, sp на x86 (загрузчик 16бит)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Обычно удобно пользоваться моделью памяти, в которой все сегментные регистры указывают в одно место. И если пишешь загрузчик, рекомендуют сегментные регистры инициализировать в самом начале. Какое именно значение сегмента выбрать -- 0 или 0x7c0 не имеет большой разницы. sp можно инициализировать так:
    start:
    ....
    mov sp, start + 512 + 1024

    это будет работать правильно для любого выбранного org и соответствующим образом инициализированного ss.
    Например:
    org 0x7c00
    start:
    mov ax, 0
    mov ss, ax
    mov sp, start + 512 + 1024


    mov ax, 0x060 ;(1024+512)/16=96=60h адрес стека после загрузчика в сегментах
    mov ss, ax ;установка адреса сегмента стека
    mov sp, 1024 ;установка указателя стека

    непонятно, почему ты решил записать в ss 0x60 а в sp -- 1024. Если ты хотел чтобы сегмент стека указывал на его дно, то должно было получиться (0x7c00 + 512) / 16 = 0x7e0.

    add ax, 0x060 ;адрес стека после загрузчика в сегментах 0x07C0+0x060

    и опять логика непонятна.
    Ответ написан
    3 комментария
  • Сегменты данных, кода это разделение для ассемблера или так хранится в машинном коде?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    На ассемблере в программе есть раздел .text, .bss, .data

    Обычно эти разделы называют секциями а не сегментами. Потому что в ELF-файлах сегменты тоже есть, но у них нет имён.
    при компиляции в машинный код там тоже так на сегменты разбит

    Разбит, да. А при линковке некоторые секции можно объединить. Обычно неизменные секции (например .text, .rodata, .tls) объединяют в одну кучу, а все изменяемые (например .bss, .data) объединяют в другую кучу. На "больших" ОС (типа linux) эти кучи эти выравнивают по границе страницы и делают неизменные секции доступными только для чтения. Это помогает сэкономить память и использовать одни и те же страницы для представления неизменных данных в разных процессах.

    для выполнения процессором

    Процессору по большому счёту всё равно как расположено в памяти то, что он выполняет.
    Ответ написан
    Комментировать
  • Почему не получается перемножать и делить assembler?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    mul al,5

    Нет такого опкода. mul вообще на непосредственное значение умножать не может. imul который может, умножает как минимум 16-битное значение в ax.
    Вместо mul умножить на 5 можно через lea (начиная с i386) либо через сдвиг на 2 и сложение.

    idiv cx,4

    idiv так не умеет. Куда проще было бы сделать sar cx, 2
    Ответ написан
    Комментировать
  • Не могу решить лабу по ассемблеру?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    mov al,x
    cmp al,a
    jg sled1
    mov bl,a
    ...


    как сделать разветвление от условия, если это условие не удовлетворяет.

    Если условие не удовлетворено, инструкция jg sled1 не совершает перехода и ты просто выполняешь следующую за ней инструкцию -- mov bl, a. Ветвления и переходы в твоём коде выглядят правильно.
    Ответ написан
    Комментировать
  • Почему программа ловит SIGSEGV на инструкции push?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Указатель стека (RSP: 0x00007FFFFFFFEA78) указывает примерно в то же место, где находится код программы (0x7fffffffea75: push rbx). Код обычно защищён от записи, соответственно записать в стек может быть нельзя по этой причине. Кроме того, если записать в стек таки можно, push rbx как раз перепишет саму себя и следующую инструкцию. Без отладчика это может работать за счёт конвейера, но под отладчиком это работать не будет.
    Ответ написан
    Комментировать
  • Правильно ли я понимаю?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Правильный ли ход мыслей?

    Да.
    Одни ассемблеры имеют одну мнемонику для нескольких опкодов с разным двоичным представлением (например на i8086 мнемоника mov выполняет множество разных видов перемещений данных между регистрами/памятью, конкретный опкод выводится из операндов), другие имеют для этого разные мнемоники (например на i8080 мнемоники mov, mvi, lda, ldax, sta, stax, lxi выполняют каждая свой вид перемещения данных между регистрами/загрузку/выгрузку из памяти/загрузку непосредственных значений).
    Ответ написан
    3 комментария
  • Отладка небольших ассемблерных кусков кода?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    только проблема в том, что в gcc формат ассемблерных вставок другой

    Разберись, потом будешь использовать его с удовольствием:
    int main() {
      int a = 1;
      int b = 3;
      int c;
    
      asm (
        "mov %[a], %[c]\n\t"
        "add %[b], %[c]\n\t"
        : [c] "=mr" (c)
        : [a] "mr" (a), [b] "mr" (b));
    
      printf("a + b = %x + %x = %x\n", a, b, c);
    }
    Ответ написан
    1 комментарий
  • Ассемблер практикуют написанием драйверов и вирусов?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как его ещё практикуют?

    чтением. Читая ассемблерный вывод компиляторов можно узнать как они реализуют те или иные вещи.
    Ответ написан
    Комментировать
  • Как получить адрес в .rdata?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Сложить смещение (0x28316dc) с адресом следующей команды (0x7ffca9332358).
    Ответ написан
    Комментировать
  • Как поместить параметр в стек?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    У тебя есть уже такая же точно ситуация с ExitProcess, и даже есть код, который это делает:
    push NULL
    call [ExitProcess]

    Что тебе мешает сделать так же?
    Ответ написан
    2 комментария
  • Убрать указание размера функции?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Меня напрягает вечное указание размера функции

    Это не размер функции. Это размер передаваемых параметров. И это часть ABI stdcall, документированная здесь, к gcc не имеющая отношения.

    Можно ли это как-то убрать, и просто объявлять: _MessageBox, _ExitProcess, как с msvcrt: _printf, __getch и т.д?

    На ассемблере? Ну разве что написав по макросу для каждой из этих функций.
    Ответ написан
  • Не работает инструкция строк movsb gas syntax, кто-нибудь может объяснить почему?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Оригинальный код прекрасно работает как есть:

    $ gcc -nostartfiles -static str.s -o str
    $ gdb ./str
    ...
    (gdb) b *0x40102f
    Breakpoint 1 at 0x40102f
    (gdb) r
    Starting program: /home/jcmvbkbc/tmp/toster/str 
    
    Breakpoint 1, 0x000000000040102f in _start ()
    (gdb) x/3b $rsi - 3
    0x402000 <source>:      1       2       3
    (gdb) x/3b $rdi - 3
    0x402010 <dest>:        1       2       3
    Ответ написан
    Комментировать
  • Почему не работает перенос ворда массива в регистр(gas syntax)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему не работает
    leaw arrayW, %si
    movw (%si), %ax


    Потому что ты в 32-битной программе пытаешься адресоваться 16-битным регистром.
    Вот так всё прекрасно работает:

    leal arrayW, %esi
    movw (%esi), %ax

    :

    $ gcc -m32 -static -nostartfiles load.s -o load
    $ gdb ./load
    (gdb) b _start
    Breakpoint 1 at 0x8049000
    (gdb) r
    Starting program: /home/jcmvbkbc/tmp/toster/load
    
    Breakpoint 1, 0x08049000 in _start ()
    (gdb) si
    0x08049006 in _start ()
    (gdb) 
    0x08049009 in _start ()
    (gdb) p/x $esi
    $1 = 0x804a000
    (gdb) p/x $ax
    $2 = 0x5
    Ответ написан
    Комментировать
  • Почему появляется ошибка?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему появляется ошибка?

    Потому что директива public недоступна в формате PE64. По логике у вас должно быть entry _start а не public _start.
    Ответ написан
    Комментировать
  • Для чего развивают GNU Assembler, когда есть Netwide Assembler с хорошей документацией?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Для чего развивают GNU Assembler

    - это ассемблер который штатно работает с gcc;
    - это ассемблер который поддерживает дофига ( больше 70 ) процессорных архитектур, а не только x86.

    GAS практически не документирован

    Чего именно тебе не хватает здесь?
    Ответ написан
    2 комментария
  • Настоящее низкоуровневое программирование на ассемблере?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    синтаксис не тот, не зажигает он меня.

    А синтаксис ассемблера и не проектировали с целью "зажигать". Его проектировали имея в виду в первую очередь простоту трансляции его в машинный код.

    получается какой-то высокоуровневый код, который меня не привлекает.

    Высокоуровневость кода не в том, как он выглядит, а в том, что он делает. Загляни, например, в исходники qemu, в основном коде вообще ни строчки на ассемблере, всё на С. Тем не менее, местами это офигенно низкоуровневый код.
    Ответ написан
    1 комментарий
  • FASM. Как объявить процедуру с аргументом - строкой?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как объявить процедуру с аргументом строкой?

    Это же ассемблер, какой "аргумент строка"? Всё -- регистры или слова в памяти.
    proc getel text
    endp

    text -- это указатель на твою строку.

    У fasm есть кучка примеров, где можно посмотреть, как там что делается.
    Ответ написан
  • Как работать с отрицательными числами в Ассемблере?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    signed __int8 numerator = 0;
    signed __int16 denominator = 0;


    extern numerator:sword
    extern denominator:sbyte
    ...
    mov denominator, al

    Ты видишь, что типы в C и в ассемблере не совпадают?
    По-хорошему надо заменить __int8 numerator на __int16 numerator, extern denominator:sbyte на extern denominator:sword а mov denominator, al на mov denominator, ax, чтобы стало как надо.
    В остальном всё выглядит хорошо.
    Ответ написан
    3 комментария