Ответы пользователя по тегу Assembler
  • В чем заключаются ошибки и как их исправить?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    А в чем заключаются эти ошибки, я не могу понять

    Когда ты на С++ пишешь строки подряд, вот так:
    "push edi"  
    "push esi"
    "mov edx,lenS"
    ...

    они склеиваются в одну строку. Когда ассемблер видит команду "push edipush esimov edx, lenS..." он резонно недоумевает.

    как их исправить

    Вставить символы конца строки \n или другие разделители инструкций в ассемблерный код.
    Ты же просил пример кода, вот же он, он компилируется и работает, воспользуйся им. Если непонятно что там написано, задавай вопросы.
    Ответ написан
  • Копирование на fasm с указанием пути?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Предполагаю как-то через ExpandEnvironmentString.
    Но не могу разобраться.

    В чём разобраться, в ExpandEnvironmentStrings? Дай ей на вход свою строку с переменными, буфер куда она запишет строку с подставленными значениями и его размер. Потом этот буфер дай на вход CopyFile.
    Ответ написан
    1 комментарий
  • Как увеличить памяти для переменных и функций ядра на C?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    При достижении или больше определённого количества переменных или функций, перестают работать все string literals в ядре C

    Определённого -- это какого?

    Вот тут
    mov bx, KERNEL_OFFSET ; Read from disk and store in 0x1000
        mov dh, 54 ;31 or 54

    ты 54 сектора ядра загружаешь в память. Есть какая-нибудь корреляция?

    как можно увеличить память для них?

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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Функция scanf крушит программу

    Скорее всего ты ошибаешься, и "программу крушит" вот это:
    push numderA
    call [printf]

    printf ожидает первым параметром форматную строку.
    Ответ написан
    6 комментариев
  • У меня программа не выводит числа в консоль, как исправить?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Моя программа … выводит адрес на месте первого числа и букву на месте второго числа.
    как исправить?

    1) посмотреть, какие параметры ожидает функция printf которую ты используешь. Форматная строка для двух целых чисел -- "%d %d".
    2) узнать, как параметры передаются в функцию и что делать после возвращения из неё. Ты используешь push razmer чтобы передать адрес переменной razmer в scanf, но в printf нужно передать не адрес переменной, а её значение. Например так:
    mov eax, [razmer]
    push eax


    Помимо этого в коде есть и другие ошибки: razmer и razmer2 определены как rb 1, а должны бы быть определены как rd 1, поскольку формат %d для scanf приведёт к записи 4 байт. %t -- нет такого формата в scanf, имелся в виду, наверно, %d.
    Ответ написан
    Комментировать
  • Почему не получается деление div на ассемблере в С++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему не получается деление div на ассемблере в С++?
    char b1 = 3, b2, b3 = 1 , res2; //1 байт el, bl, ah    ]]  cbw -> short
      short w1= 1000, w2 = 500, w3 = 2;
    //(w1 - w2) * w3 / b1

    div bl

    Потому что (1000 - 500) * 2 / 3 = 333, а это не влезает в один байт результата, а значит ты получаешь исключение. См.
    Ответ написан
    Комментировать
  • Почему не работает inportb(0x60)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    во-первых компилятор даёт предупреждение, … , но ошибки не производит. Я спокойно линкую файл недо-драйвера с основным ядром, (конечный результат - .efi),

    Дело в том, что у EFI-приложений нет динамической линковки, а неопределённый символ после копирования из .so в .efi просто ссылается в никуда. Если вывести неопределённые символы для bootx64.so, то inportb будет среди них:
    objdump -t bootx64.so | grep UND
    0000000000000000         *UND*  0000000000000000 inportb


    В qemu результат вызова этой функции выглядит так:
    Trace 0: 0x7fb15d338e80 [0000000000000000/000000007e6e22de/0x40c2b0]
    ----------------                      
    IN: 
    0x7e6e2081:  bf 60 00 00 00           movl     $0x60, %edi
    0x7e6e2086:  b8 00 00 00 00           movl     $0, %eax
    0x7e6e208b:  e8 90 57 00 00           callq    0x7e6e7820
    
    Trace 0: 0x7fb15d3390c0 [0000000000000000/000000007e6e2081/0x40c2b0]
    ----------------                      
    IN: 
    0x7e6e7820:  af                       scasl    (%rdi), %eax
    0x7e6e7821:  af                       scasl    (%rdi), %eax
    0x7e6e7822:  af                       scasl    (%rdi), %eax
    0x7e6e7823:  af                       scasl    (%rdi), %eax
    0x7e6e7824:  af                       scasl    (%rdi), %eax
    0x7e6e7825:  af                       scasl    (%rdi), %eax
    0x7e6e7826:  af                       scasl    (%rdi), %eax
    0x7e6e7827:  af                       scasl    (%rdi), %eax
    0x7e6e7828:  af                       scasl    (%rdi), %eax
    0x7e6e7829:  af                       scasl    (%rdi), %eax
    0x7e6e782a:  af                       scasl    (%rdi), %eax
    0x7e6e782b:  af                       scasl    (%rdi), %eax
    …


    С другой стороны, если предоставить такую функцию:
    unsigned char
    inportb(unsigned short port)
    {
            unsigned char v;
            asm volatile ("in {%1|%b0}, {%b0|%1}\n" : "=a"(v) : "d"(port));
            return v;
    }

    то она прекрасно вызывается и возвращает значение.

    Можно добавить опцию -zdefs в команду линковки чтобы получать ошибку линковки при наличии ссылок на неопределённые символы.

    Чтобы посмотреть, какой именно код выполняется, я запускаю qemu с монитором в консоли (дополнительным ключом -monitor stdio). Я нажимаю ESC когда в QEMU запускается tianocore и выбираю Boot Manager -> EFI Internal Shell, а там пишу fs0:efi\boot\bootx64.efi, после этого в мониторной консоли включаю логгирование (командами logfile log, log in_asm,exec), после чего нажимаю enter в консоли EFI. После этого можно смотреть в файл log и искать в нём знакомые байты из objdump.
    Ответ написан
  • Как правильно проинициализировать контроллер прерывания?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    По сути pic должен генерировать прерывания 18 раз в секунду

    По сути не PIC, а таймер. А в твоём коде не видно ни как ты инициализировал таймер, ни что таймерное прерывание разрешено в PIC.
    Ответ написан
    2 комментария
  • Как можно игнорировать элементы строки?

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

    ты написал что-то непонятное.

    надо сравнить если символ не входит в диапазон 31h-39h, то надо идти дальше по элементу массива

    это можно сделать например так:

    metka:  
    
        mov ax,0
        mov al, StringT[si]
        sub al, 49
    
        jl next      # перейти к следующей цифре, если код текущей меньше '1'
        cmp al, 9
        jnl next     # перейти к следующей цифре, если текущая больше 9
    
        mov bl, al
        shl bl, 1 ;умножение на 2, т.к. размер адреса - 2 байта
        
        xor ax, ax
        
        mov dx, offset List[bx]
        mov ah, 09h
        int 21h
    next:
        add si, 1
        loop metka
    Ответ написан
  • Почему время выполнения следующих SIMD инструкций такое?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я не нашёл ничего почитать, но нашёл рекомендацию использовать llvm-mca, и для вариантов кода использующих SSE/AVX она дала мне показатели производительности которые совпали с наблюдаемыми на практике. Cоответственно, при желании можно почитать исходники llvm-mca (и добраться до модели пайплайна где-то в недрах llvm).

    Почему пятый вариант не выполняется в 4 раза быстрее, чем первый?

    Потому что скорость выполнения связана со сложностью опкодов. Так, выполнение vmulpd в пятом варианте занимает 4 такта и полностью перекрывается с остальными инструкциями цикла, так что даже нет смысла делать его короче, меняя add+cmp+jne на sub+jne.
    Ответ написан
    2 комментария
  • Как найти длину массива?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    MaxSymb Db 9
    RealSymb Db ?
    StringT db 1 dup (' ')

    Здесь должно быть StringT db 9 dup (' '), иначе ввод затрёт то что там дальше в памяти лежит.

    я пытался и делать так mov cx, InBuff[0] , mov cx, InBuff[1] без разницы.

    Эти инструкции загружают 16-битный регистр из памяти, а значение длины -- 8-битное. Правильно было бы как-нибудь так: mov cl, [RealSymb]

    len equ $ - StringT - не выходит, тоже 1 выдаёт

    Это вообще определяет константу, значение которой равно разности текущего адреса и адреса StringT. Если это делать в твоей программе сразу следом за определением StringT, то 1 и получится, потому что длина StringT у тебя -- 1 байт.
    Ответ написан
    6 комментариев
  • NASM смещение в массиве (invalid effective address)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как в nasm можно выполнить смещение?
    [string + cx]
    invalid effective address

    дело не в ассемблере, а в устройстве процессора. x86 имеет в 16-битном режиме режим адресации "база + смещение", но базой могут выступать только регистры bx, si, di и bp. При этом di адресуется относительно сегментного регистра es, а bp адресуется относительно сегментного регистра ss.
    Это задокументировано в табличке 2-1 "16-Bit Addressing Forms with the ModR/M Byte" в томе 2А Intel Developer Manual'а, доступного, например, здесь.
    Ответ написан
  • Как сделать посекторную запись на диск?

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

    "Посекторно считывать диск" можно, например, понимая структуру файловой системы и читая файл с ядром ОС. Номера секторов при этом могут не идти друг за другом, а определяться какой-нибудь служебной таблицей файловой системы, например FAT. В этом случае ядро для загрузки можно будет записывать просто как файл на файловую систему.
    Ответ написан
    Комментировать
  • Есть ли у регистров адреса как у памяти?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Есть ли у регистров адреса как у памяти?

    Адреса есть (и эти адреса кодируются в инструкциях обращающихся к регистрам напрямую), но обычно не как у памяти. Наличие у регистров адресов как у памяти зависит от архитектуры. Кроме упомянутого AVR такая фича есть, например, у 8051.

    Почему нет?

    Потому что доступ к памяти и доступ к регистрам устроены сильно по-разному в серьёзных процессорах.
    Ответ написан
    Комментировать
  • Правильно ли я хочу использовать либы в ассемблере?

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

    Вполне.
    Ответ написан
    Комментировать
  • Как правильно в регистр задать строку через at&t втроенным ассемблером?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я вижу вот такой рабочий вариант (и при этом не уверен в том, какой порядок байт имеется в виду в оригинальной инструкции):
    movl    ((((('V' << 8) + 'M') << 8) + 'X') << 8) + 'h', %eax
    Ответ написан
  • Как перевести inline assembler в файл?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    компилятор ругается что
    mov esi, CPUInfo
    mov eax, InfoType
    undefined

    Ну правильно ругается. Это же не глобальные имена и их же нет в ассемблерном исходнике?
    Можно поправить определение функции getCpuID вот так: getCpuID PROC PUBLIC, CPUInfo, InfoType.
    И стоит прочитать вот это чтобы представлять, как параметры передаются в функции и что ещё нужно делать, чтобы всё работало.
    Ответ написан
    Комментировать
  • Почему function definition not found?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    у функии нет определения, хотя оно в asm-файле, как это можно исправить

    поменять в ассемблерном исходнике square PROC на square PROC PUBLIC.
    Убедиться, что ассемблерный исходник помпилируется и линкуется с проектом.
    Ответ написан
  • Почему не работает данная прога?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему не работает данная прога?

    Она на самом деле работает. Просто вывод попадает в точности на введённую строку, из-за чего непонятно, что он случился. Вот с таким изменением будет видно, что работает:

    ...
      call input
      mov dl, 0ah
      mov ah, 2
      int 21h
      call output
      ...
    Ответ написан
  • Как войти в виртуальный режим из защищенного?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    На OSDev Wiki прочитал что работать с pci невозможно из защищённого режима в котором я и "сижу".

    где именно прочитал? Прочитай внимательно ещё раз. Для взаимодействия с конфигспейсом PCI на x86 нужно использовать порты ввода/вывода 0xCF8 и 0xCFC. Через них можно настроить BARы PCI-устройства, т.е. разместить его регистры/память в физическом адресном пространстве.

    Как тогда войти в виртуальный режим?

    в какой "виртуальный" режим?
    Ответ написан
    Комментировать