Задать вопрос
Ответы пользователя по тегу Assembler
  • Проверите программу вычисления среднего арифметического на Assembler?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    чисел, которые находятся в памяти данных.

    Где загрузка данных и памяти в регистры?
    Почему все brcc переходят на add_8?
    Почему в следующем фрагменте и из младшего и из старшего байта суммы вычитается counter?
    sub sum_l,counter
        sbc sum_h,counter

    Почему из цикла деления выход только при переносе в минус? Что если разделится нацело?
    Ответ написан
    Комментировать
  • Поможете найти ошибку?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    ты потерял int 10h перед jmp text прямо над меткой backpace:
    Ответ написан
    Комментировать
  • Как загрузить код с диска в оперативную память в реальном режиме ассемблера?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Головки нумеруются с 0. Поправь в первом примере mov dh, 1 на mov dh, 0 и увидишь свои &.&.&.
    Ответ написан
    1 комментарий
  • Существует ли отладчик, который позволяет делать брекпоинт с условиями?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я хочу произвести отладку и остановить программу когда будет соблюдаться определенное условие. Допустим сумма регистров eax+ebx будет равна 65463.

    Для совсем уж произвольного условия, типа того, что вы написали, готовых средств скорее всего нет.
    Если вам нужно остановиться, когда программная переменная в памяти принимает определённое значение -- искать в вашем отладчике по слову watchpoint. В gdb, например, можно поставить watchpoint на переменную, а в commands вписать код, который будет продолжать выполнение, если значение переменной не то, что вам нужно, например:
    $ cat > main.c
    int v;
    
    static void f(int *p)
    {
            int i;
    
            for (i = 0; i < 20; ++i)
                    *p = (i - 10) * (i - 10);
    }
    
    int main()
    {
            f(&v);
            return 0;
    }
    $ gcc -g2 -o watch main.c     
    $ gdb ./watch              
    ...
    Reading symbols from ./watch...done.
    (gdb) start
    Temporary breakpoint 1 at 0x4004ec: file main.c, line 13.
    Starting program: /home/jcmvbkbc/tmp/toster/watch/watch 
    
    Temporary breakpoint 1, main () at main.c:13
    13              f(&v);
    (gdb) watch v
    Hardware watchpoint 2: v
    (gdb) commands 
    Type commands for breakpoint(s) 2, one per line.
    End with a line saying just "end".
    >if (v != 4)
     >continue
     >end
    >end
    (gdb) c
    Continuing.
    ...
    Hardware watchpoint 2: v
    
    Old value = 9
    New value = 4
    f (p=0x600904 <v>) at main.c:7
    7               for (i = 0; i < 20; ++i)
    (gdb)
    Ответ написан
    Комментировать
  • Как послать набор символов в qemu, если там нет ОС?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Можно научить интерпретатор читать из последовательного порта, присоединить последовательный порт QEMU к stdio опцией -serial и писать туда например так:
    echo '++++++' | qemu-system-... -nographic -monitor none -serial stdio
    Ответ написан
    Комментировать
  • В асме проблема с флагом четности, есть ли ошибка в программе?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert

    mov al,ds:[si]
    jp    m4             ;переход, если установлен флаг четности P=1
    jnp   m3             ;переход, если установлен флаг четности P=0

    1) флаг P -- это не признак чётности числа, а признак наличия нечетного числа единичных битов в регистре. Чётность числа зависит от 0 или 1 в его младшем разряде.
    2) Загрузка значения в регистр не меняет никакие флаги.

    Т.е. правильно будет, например, так:
    mov al,ds:[si]
    test al, 1
    jz    m4             ;переход, если число чётное
    jmp   m3             ;переход, если число нечётное
    Ответ написан
    2 комментария
  • Дизассемблер для PE 64 bit Windows?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Единственное, что требуется - выводить удобный листинг.

    objdump
    Ответ написан
    Комментировать
  • Какие параметры надо передать в ReadConsole?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    stdcall [ReadConsole],GENERIC_READ,Message,13,0,0

    Первым параметром надо дескриптор файла консоли передать. GENERIC_READ -- это не файловый дескриптор, это требуемый доступ к файлу, чтобы ReadConsole могла из него читать. Требуемый дескриптор можно получить вызовом GetStdHandle(STD_INPUT_HANDLE).
    И я не уверен, что lpNumberOfCharsRead может быть NULL.
    Ответ написан
    Комментировать
  • Как вводится двоичное число в консоль в TASM Ассемблер?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Прочитать строку из стандартного ввода функцией 3fh, поместить в результат 0, а дальше идя по прочитанной строке слева направо сдвигать результат влево на 1 бит, а в младший бит класть 0 или 1, в зависимости от текущего символа в строке.
    Ответ написан
    Комментировать
  • Почему при вызове функции 4ch прерывания 21h резидентный обработчик падает?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    mov dx, (start - new_int09h +0fh)/16

    А почему такой размер резервируемой памяти? Это exe или com?
    У вас есть функции, вызываемые из резидентной части, лежащие после start:
    write_data портит ds.
    Ответ написан
    3 комментария
  • Не работает деление в ассемблере. Что я сделал не так?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    mov edx, [arr16] ; заносим в edx первый элемент массива
    mov eax, [arr16+4] ; заносим в eax второй элемент массива

    Начнём с того, что в edx нужно поместить старшую часть делимого, а в eax -- младшую, а на x86 слова в память записываются младшей частью вперёд (little endian).

    Если результат деления не помещается в eax вы получите исключение #DE, а при делении числа 0x0000000100000000 (а именно его вы делите, загрузив в eax 0 а в edx 1) на 1 результат определённо в 32 бита не влезет.

    Вообще, глядя на ваши вопросы создаётся впечатление, что вы хотите реализовать на ассемблере длинную арифметику. Но длинное деление таким образом, как вы пытаетесь сделать, точно не работает. Вам надо либо побитово делить "в столбик", либо аппроксимировать каким-то рядом (либо ещё как-то, как мне не пришло в голову).
    Ответ написан
    1 комментарий
  • Почему такой странный вывод?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    А вы можете объяснить, что у вас происходит здесь:
    srav:
        repe cmps s1,s2
        mov bx,0
        dec di
        mov s3[bx],di
        inc di
        inc bx
        loop srav


    Кроме того, для вывода строки функцией 9 int21 она должна заканчиваться символом '$'.
    Ответ написан
  • Почему сопроцессор в тысячу раз медленнее процессора?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Кто подскажет, что я делаю не так?


    Это:
    clock_t strt = clock();
    ...
    clock_t bk1 = clock() - strt;
    ...
    clock_t bk2 = clock() - bk1;

    bk1 -- это разность абсолютных времён, т.е. продолжительность, а bk2 -- это разность абсолютного времени и продолжительности, т.е. абсолютное время.

    Ок, после исправления этого бага я вижу проблему с переполнением стека сопроцессора: fadd не сдвигает стек обратно и fld его очень быстро переполняет.

    С переполнением стека я тоже наблюдаю, что fpu работает ~ в 1000 раз медленнее чем ALU. Но если сбалансировать загрузки, операции и выгрузки так, чтобы стек не переполнялся у меня все работает со сравнимой скоростью. Подозреваю, что там случается исключение, но оно не фатальное и молча глотается ядром.

    Я тестировал следующий код (выкинул вообще всё лишнее):
    #include <stdio.h>
    #include <inttypes.h>
    #include <time.h>
    
    #define MAX_I 4000000
    
    int32_t rezult[64];
    
    void StartPR(int str)
    {
            asm volatile ("mov $4000000, %%eax\n\t"
                          "xor %%ebx, %%ebx\n\t"
                          "xor %%ecx, %%ecx\n\t"
                          "xor %%edx, %%edx\n"
    
                          "circle:\n\t"
                          "add %%eax, %%ebx\n\t"
                          "add %%eax, %%ecx\n\t"
                          "add %%eax, %%edx\n\t"
                          "dec %%eax\n\t"
                          "jnz circle\n\t" ::: "memory");
    }
    
    void StartMMX(int str)
    {
            double v = 4000000;
            asm volatile ("mov $4000000, %%eax\n\t"
                          "fldz\n\t"
    
                          "circle2:\n\t"
                          "fld %0\n\t"
                          "faddp \n\t"
                          "fld %0\n\t"
                          "faddp \n\t"
                          "fld %0\n\t"
                          "faddp \n\t"
                          "fld %0\n\t"
                          "faddp \n\t"
                          "sub $4, %%eax\n\t"
                          "jnz circle2\n\t"
                          "fstp %0" :"+m"(v):: "memory");
    }
    
    void stardThreads(int numOfThread)
    {
            printf("threads: %i", numOfThread);
            int i = 0;
            clock_t strt = clock();
            StartPR(0);
    
            clock_t strt2 = clock();
            clock_t bk1 = strt2 - strt;
    
            StartMMX(i);
            clock_t bk2 = clock() - strt2;
            printf("time block1:%i, block2:%i, tics per second:%i\n", (int32_t)bk1, (int32_t)bk2, CLOCKS_PER_SEC);
    }
    
    int main(int argc, char *argv[])
    {
            int i;
            for (i = 1; i < 9; i++)
                    stardThreads(i);
    
            return 0;
    }


    Результат:
    threads: 1time block1:6949, block2:9311, tics per second:1000000
    threads: 2time block1:4061, block2:7872, tics per second:1000000
    threads: 3time block1:3901, block2:7398, tics per second:1000000
    threads: 4time block1:3615, block2:7045, tics per second:1000000
    threads: 5time block1:3389, block2:6716, tics per second:1000000
    threads: 6time block1:3250, block2:6342, tics per second:1000000
    threads: 7time block1:3189, block2:6036, tics per second:1000000
    threads: 8time block1:3032, block2:5885, tics per second:1000000
    Ответ написан
    4 комментария
  • Как вывести формулу из дизассемблерного кода?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как вывести формулу из дизассемблерного кода

    Выписав выражения элементарных математических действий соответствующих ассемблерным командам и подставив выражения друг в друга, согласно тому, как использованы регистры и переменные в памяти.
    Например:
    mov 0x10(%ebp),%edx
    -- это "поместить в edx третий параметр функции (назовём их a (0x8(%ebp)), b (0xc(%ebp)) и c (0x10(%ebp))): edx = c"

    mov %edx,%eax
    -- "поместить в eax edx, который равен c, т.е. eax = c"

    shl $0x2,%eax
    -- сдвинуть eax на 2 влево, т.е. умножить на 4, т.е. eax = c * 4

    и т. д.

    Результат -- то что останется в eax перед возвратом.
    Ответ написан
    Комментировать
  • Чем ASEM51 отличается от A51?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    чем кросс-ассемблер отличается от макроассемблера?

    Макроассемблер -- это ассемблер поддерживающий макросы.
    Кросс-ассемблер -- это ассемблер, генерирующий код для процессора, архитектура которого отлична от той, на которой он сам выполняется.
    Макроассемблер может быть кросс-ассемблером.
    Ответ написан
    Комментировать
  • Вопрос о сегментных регистрах и процессе загрузки регистра DS?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    откуда программа может знать где окажутся ее данные чтобы самой указать это значение?

    Она не может знать до загрузки, поэтому все сегментные части адресов записаны как смещения относительно начала программы, т.е. как будто программа будет загружена по адресу 0. EXE-файл содержит таблицу релокаций, это массив смещений относительно начала программы, по которым находятся сегментные части адресов. Загрузчик EXE-файла проходит по этому массиву и прибавляет к словам в памяти фактический сегментный адрес, по которому программа загружена.
    Ответ написан
    2 комментария
  • Как поделить числа в неполных регистрах?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Помимо ручного обнуления верхних половин 16-битных регистров есть (начиная с i386) инструкции movzx и movsx, перемещающие данные между регистрами разного размера, расширяя их нулём или знаком.
    Т.е.
    mov al, dl
    mov ah, 0

    это
    movzx ax, dl
    Ответ написан
    Комментировать
  • Зачем нужно выравнивание (ассемблерного) кода при компиляции (линковке)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Зачем нужно выравнивание (ассемблерного) кода

    Потому что так требует меньше кеша и быстрее работает.
    Кроме того, на некоторых архитектурах некоторые команды перехода могут переходить только по выровненным адресам.
    в оперативной памяти доступ к любому участку занимает одинаковый промежуток времени

    Нет.
    Ответ написан
    Комментировать
  • Как исправить код так, чтобы заменялись все символы (tasm/masm)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Что-то такое должно быть во втором примере:

    ...
      lea di, s 				; s строка приёмник
    
      cld 					; читаем строку слева направо
    m0:
      mov al, ast
      repne scasb  				; поиск совпадения
      jne m1				; если символ не найден переход на m1
    
      mov al, oct
      dec di
      stosb  				; замена символа
      jmp m0
    
    m1:	mov ah, 09h
      ...
    Ответ написан
  • Не пойму почему метка не работает так как нужно masm32?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    mov eax,offset i
    mov ebx,zero
    next:cmp eax,pr
    jne nextEl; если пробел равен элементу строки то должно перейти на следующую строку

    ...а сравниваются, между тем, адрес строки и адрес переменной содержащей пробел.
    Должно быть как-то так:
    mov eax,offset i
    mov ebx,zero
    next:cmp byte ptr [eax], 20h
    jne nextEl

    Дальше код тоже барахло.
    Изучите то, как записываются разные виды адресации в вашем ассемблере. Например: www.c-jump.com/CIS77/ASM/Addressing/lecture.html#R...
    Ответ написан
    1 комментарий