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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    выдает непонятную фигню

    Ну в программе нет проверки ввода, поэтому если вводить непонятную фигню, то и выводить она будет непонятную фигню. А если вводить цифры, так чтобы сумма не превышала 9, то приведённая программа прекрасно работает.
    Это, правда не значит, что в этой программе нет ошибок. Я вижу как минимум одну:
    res resb 1 
    …
    mov [res], eax

    классическое переполнение буфера. Её наличие, правда, на результат повлиять не может.
    Ответ написан
    Комментировать
  • Ошибка bin: fatal: more than one input file specified: BootLoader.asm?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    more than one input file specified
    nasm -felf64 bin BootLoader.asm -o BootLoader.bin

    nasm как бы говорит тебе: "выбери, или ты ассемблируешь bin или BootLoader.asm"
    Если же ты хотел формат 'bin', то выкинь -felf64 и замени его на -fbin.
    Тебе, правда, при этом прийдётся добавить что-нибудь типа use64 в исходник, чтобы сказать, что он не 16-битный.
    Ну и к тому же message у тебя лежит перед кодом, в той же секции, хороший bin из этого не получится.
    Ответ написан
  • Что нужно написать, чтобы загрузчик ос передавал управление коду в втором секторе?

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

    Нужно написать запрос в гугле: загрузчик ос и потом немного почитать.
    Ответ написан
    Комментировать
  • Почему не работает клавиатура?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    почему-то не работает прерывание 0х20 для клавиатуры

    я не буду отлаживать твой код, но предложу тебе несколько вопросов, которые помогут тебе посмотреть в нужные места:
    - посылает ли клавиатура вообще IRQ?
    - настроен ли контроллер прерываний на приём IRQ от клавиатуры?
    - размаскирована ли линия IRQ от клавиатуры в контроллере прерываний?
    - настроен ли контроллер прерываний на то чтобы вызывать int 0x20 в ответ на IRQ от клавиатуры? [1]
    - получает ли процессор прерывание от контроллера прерываний?
    - настроена ли запись в IDT для int 0x20 на вызов твоего обработчика?
    - разрешены ли прерывания в процессоре?

    [1] Коль скоро здесь ты установил базовый вектор первого PIC в 0x20, то клавиатура, посылая IRQ1, должна вызывать int 0x21.
    Ответ написан
    Комментировать
  • Почему Qemu вылетает?

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

    Эта часть вопроса не даёт нам никакой полезной информации. Рассказывай что делал, а мы попробуем понять, что пошло не так в твоём расследовании.
    Ответ написан
  • Почему не работает печать?

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

    Иван Четчасов, этого более чем достаточно, чтобы понять, что происходит. По шагам:
    - надо узнать адрес метки printsz
    - найти в логе qemu выполнение кода по этому адресу
    - проследить за тем, какой код выполняется и что оказывается в регистрах
    - понять что не так.
    Ответ написан
    Комментировать
  • Как настроить IDT в защищенном режиме процессора(assembler)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я гуглил, но понятного объяснения не нашел.

    Ок, вот первая ссылка из гугла по запросу "x86 idt". Скажи, есть ли что-то на этой странице, что вызывает трудности?

    Или, если тебе больше нравятся оригинальные документы, вот классическая книжка об x86 от интела. Для понимания программирования idt следует прочитать главу 6.5 "Interrupts and exceptions" в первом томе для ознакомления с общей картиной, и главу 6 "Interrupt and exception handling" в третьем томе для понимания деталей.
    Ответ написан
  • Почему ВМ перезагружается?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я пишу ос и у меня возникла проблема

    Возникла проблема -- отлаживай.
    Разберись, что за адрес у тебя загружается здесь в GDT.

    Вот так это можно пофиксить.
    Ответ написан
  • Почему ядро странно себя ведет?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я пишу новую операционную систему и столкнулся с непредвиденным поведением ядра

    Обычно в этот момент люди начинают пользоваться отладчиком.

    проблема в файле kernel\kernel.asm

    Нет. Ядро твоё не запускается, потому что бутлоадер пытается загрузить его поверх собственного кода:

    0x00008122:  bb 00 81                 movw     $0x8100, %bx
    0x00008125:  50                       pushw    %ax
    0x00008126:  b8 00 00                 movw     $0, %ax
    0x00008129:  8e c0                    movw     %ax, %es
    0x0000812b:  58                       popw     %ax
    0x0000812c:  cd 13                    int      $0x13

    -- это вызов int 13 из бутлоадера, посмотри на адреса. Вот куда возвращается выполнение после этого int 13:

    0x0000812e:  00 00                    addb     %al, (%bx, %si)
    0x00008130:  00 00                    addb     %al, (%bx, %si)
    0x00008132:  00 00                    addb     %al, (%bx, %si)
    0x00008134:  00 00                    addb     %al, (%bx, %si)
    0x00008136:  00 00                    addb     %al, (%bx, %si)
    0x00008138:  00 00                    addb     %al, (%bx, %si)
    0x0000813a:  00 00                    addb     %al, (%bx, %si)
    0x0000813c:  00 00                    addb     %al, (%bx, %si)
    0x0000813e:  00 00                    addb     %al, (%bx, %si)
    0x00008140:  00 00                    addb     %al, (%bx, %si)
    0x00008142:  00 00                    addb     %al, (%bx, %si)
    0x00008144:  00 00                    addb     %al, (%bx, %si)


    Такие дампы ты можешь получить запуская своё ядро в qemu следующим образом:
    qemu-system-i386 -hda collector.bin -d in_asm,exec,cpu -D log
    Ответ написан
    7 комментариев
  • Как запустить другую программу на NASM-е?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как из файла ассемблера (NASM) запустить exe-шник?

    Системным вызовом (т.е. вызовом функции ядра ОС, например execve), либо вызовом библиотечной функции, которая сделает этот системный вызов за тебя (например функции библиотеки C system или функции win32 API CreateProcess).

    Не отдельно, а как-будто ассемблерский файл это и есть ос?

    Загрузить исполняемый файл в память, если он не статически слинкован -- загрузить все его зависимости (и все их зависимости, соответственно), связать вызовы сделанные через таблицы импорта, выполнить релокации для объектов, которые загружены не по адресам для которых они собраны, очистить bss, выделить стек, инициализировать регистры для первого потока, перейти в точку старта. Обычно ядро делает только загрузку исполняемого образа и динамического линковщика, инициализацию bss, выделение стека и запуск первого потока, а дальше динамический линковщик делает всё остальное в юзерспейсе.
    Ответ написан
    Комментировать
  • В чем заключаются ошибки и как их исправить?

    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 комментария