Ответы пользователя по тегу Assembler
  • Как организовать массив состоящий из разных участков памяти?

    @VitalyChaikin
    Во втором массиве хранить смещение элементов первого массива;
    mov bx, Mass2[ i ] ; Получаем offset элемента 
    mov ax, Mass1[bx] ; Получаем значение элемента в ax
    Ответ написан
    Комментировать
  • Как выучить язык ассемблера?

    @VitalyChaikin
    Для начала в Стиме или на торрентах найди TIS-100 и реши все задачи ...
    Ответ написан
  • Что происходит во время прерывания в многопоточной среде? Или прерывания посреди прерывания?

    @VitalyChaikin
    Многопоточная среда - это операционная система, при этом каждое приложение выполняющееся в этой среде - однопоточное ! (как правило в 99.99%)
    Есть такое понятие STA - single thread apartment model; Так вот приложения компилируются в такой модели. Это означает - что внутри выполняющегося приложения есть только один поток* и пока выполняется код в этом потоке, все события операционной системы добавляются в стек, до тех пор пока приложение само не считает эти события
    Ответ написан
    Комментировать
  • Почему вычитается 32?

    @VitalyChaikin
    https://en.wikipedia.org/wiki/X86_calling_conventions
    int callee(int, int, int);
    
    int caller(void)
    {
    	return callee(1, 2, 3) + 5;
    }
    On x86, it might produce the following assembly code (Intel syntax):
    
    caller:
        ; make new call frame
        ; (some compilers may produce an 'enter' instruction instead)
        push    ebp       ; save old call frame
        mov     ebp, esp  ; initialize new call frame
        ; push call arguments, in reverse
        ; (<b>some compilers may subtract the required space from the stack pointer,
        ; then write each argument directly, see below.
        ; The 'enter' instruction can also do something similar)
        ; sub esp, 12      : 'enter' instruction could do this for us</b>
        ; mov [ebp-4], 3   : or mov [esp+8], 3
        ; mov [ebp-8], 2   : or mov [esp+4], 2
        ; mov [ebp-12], 1  : or mov [esp], 1
        push    3
        push    2
        push    1
        call    callee    ; call subroutine 'callee'
        add     esp, 12   ; remove call arguments from frame
        add     eax, 5    ; modify subroutine result
                          ; (eax is the return value of our callee,
                          ; so we don't have to move it into a local variable)
        ; restore old call frame
        ; (some compilers may produce a 'leave' instruction instead)
        mov     esp, ebp  ; most calling conventions dictate ebp be callee-saved,
                          ; i.e. it's preserved after calling the callee.
                          ; it therefore still points to the start of our stack frame.
                          ; we do need to make sure
                          ; callee doesn't modify (or restore) ebp, though,
                          ; so we need to make sure
                          ; it uses a calling convention which does this
        pop     ebp       ; restore old call frame
        ret               ; return
    Ответ написан
    Комментировать
  • Как обрезать строку в fasm?

    @VitalyChaikin
    Во-первых: sub eax, 10 // а надо sub eax, 11 // т.к. строка начинается с x[0] и заканчивается на x[eax-1]
    Во-вторых: ну и чего ты растерялся на процедуре cut ?
    // mov ecx, [eax+ebx] // мы вообще то байты считываем из x
    mov ecl, byte ptr [eax+ebx]
    ; далее нам надо этот байт переводить в десятичное число (умножать на разряд (10 в степени) и прибавлять к итоговому результату
    Ответ написан
    Комментировать
  • Что делает команда lea (ассемблер)?

    @VitalyChaikin
    LEA ПРИЁМНИК, ИСТОЧНИК

    это то же самое, что и

    MOV ПРИЁМНИК, offset ИСТОЧНИК
    Ответ написан
    Комментировать
  • Как вывести двумерный массив?

    @VitalyChaikin
    Так он же пишет - operand sizes do not match
    Вначале посчитай 8*(field.size_n*rcx + rdx) помести в bx, а только потом обращайся:
    mov ax, [field.grid][bx]
    Ответ написан
  • Маркетинговые ходы вокруг языка Ассемблер?

    @VitalyChaikin
    Если доходчиво, то в этом и отличие высокоуровневого языка от низкоуровневого;
    Высокоуровневый -> Компилятор в низкоуровневый язык на заданной архитектуре -> исполняемый код
    Низкоуровневый язык на заданной архитектуре -> исполняемый код
    Легко заметить что Ассемблер (он же Низкоуровневый язык на заданной архитектуре) уже включает в себя заданную архитектуру, поэтому и не может портироваться на другую архитектуру;
    Ответ написан
    Комментировать
  • Могу ли я лучше сделать?

    @VitalyChaikin
    до инструкции cmp ebx, eax нет инициализации ebx это наверняка ошибка :)
    Ответ написан
  • Линейный аддресc? Умножение на 16, как это работает вообще и за чем в модели памяти, 32 бит, с 32 бит регистрами?

    @VitalyChaikin
    Какая-то каша в ваших рассуждениях;
    Есть адресное пространство скажем 1000 байт, а наш регистр адресации не может хранить такое большое число = 1000;
    Тогда для того чтобы получить линейный адрес нам необходимы ДВА регистра; R1 и R2
    Таким образом чтобы R1*(максимальное_число_которое_может_храниться_в_регистре + 1) + R2 >= 1000
    {максимальное_число_которое_может_храниться_в_регистре = 15} от 0 до 15 может хранить байт поэтому умножение производится на 16
    К адресу 1000 мы можем обратиться только ОДНИМ способом: R1 = Целое(1000 / 16) ; R2 = ОстатокОтДеления(1000 / 16)
    Ответ написан
  • Лишняя инструкция в дизассемблированном коде ассемблера?

    @VitalyChaikin
    Компилятор работает с некоторыми блоками*
    блок1 - он откомпилировал
    блок2 - снова откомпилировал
    для него что происходит в блок1 и блок2 тёмный лес, и то что последняя инструкция из блок1 и первая из блока2 делают одно и тоже - совершенно не очевидно. Просто так совпало.
    Ответ написан
  • Ассемблер, я правильно понимаю что по умолчанию в регистрах 0x00?

    @VitalyChaikin
    Я рекомендую обязательно смотреть документацию, чтобы четко понимать какие регистры используют входные данные, и куда помещается результат.
    push и pop в данном случае используются чтобы сохранить значения регистров, а затем восстановить их. Однако вызываемые функции НЕ ИСПОЛЬЗУЮТ эти регистры. И сохранение/восстановление не имеет никакого смысла.
    int 10
    0eH писать символ на активную видео страницу (эмуляция телетайпа)
    вход: AL = записываемый символ (использует существующий атрибут)
    BL = цвет переднего плана (для графических режимов)

    display_letter:
    mov ah, 0x0E ; код функции которая выводит букву на экран
    mov bx, 0x000F ; 00 - нулевая страница; BL - цвет буквы
    int 0x10 ; обращаемся к BIOS, чтобы она нарисовала букву

    int 16
    00H читать (ожидать) следующую нажатую клавишу
    выход: AL = ASCII символ (если AL=0, AH содержит расширенный код ASCII )
    AH = сканкод или расширенный код ASCII

    read_keyboard:
    mov ah, 0x00 ; код функции считывающей символ с клавиатуры
    int 0x16 ; обращаемся к BIOS чтобы выполнить ее
    Ответ написан