• Как выучить язык ассемблера?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как выучить язык ассемблера?

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

    Исходники на ассемблере, которые любой компилятор тебе нагенерирует, справочник по инструкциям твоего процессора (например 2й том Intel developer manual) и гугл. Просто бери, читай и разбирайся зачем так.
    Ответ написан
    Комментировать
  • Нужно найти сумму отрицательных чисел. Что с кодом?

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

    Переменная используется без инициализации.
    Замени int sum; на int sum = 0;
    Ответ написан
    1 комментарий
  • Как узнать возраст файла в Ассемблере?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как мне найти возраст файла?

    Сравнить creationTime который возвращает GetFileTime с текущим временем которое возвращает GetSystemTimeAsFileTime. 3 дня -- это 3 * 24 * 60 * 60 * 10000000 100-наносекундных интервала (в таких единицах измеряется FILETIME).
    Чтобы упростить себе задачу можно сравнивать только старшие части (dwHighDateTime) структур FILETIME, вес младшей части -- 429 секунд, меньше 10 минут.
    Типа того:

    invoke GetFileTime, hFile, addr ftCreate, NULL, NULL
      invoke GetSystemTimeAsFileTime, addr ftNow
      mov eax, ftNow.dwHighDateTime
      sub eax, ftCreate.dwHighDateTime
      cmp eax, (3 * 24 * 60 * 60 * 10000000 / 0x100000000)
      jg <файл старше 3 дней>
      /* иначе файл младше 3 дней */

    Если упрощать не хочется и нужно отмерить в точности 3 дня, то хвост можно переписать так:
    mov eax, ftNow.dwHighDateTime
      sub eax, ftCreate.dwHighDateTime
      cmp eax, (3 * 24 * 60 * 60 * 10000000 / 0x100000000)
      jg <файл старше 3 дней>
      jl <файл младще 3 дней>
      mov eax, ftNow.dwLowDateTime
      sub eax, ftCreate.dwLowDateTime
      cmp eax, (3 * 24 * 60 * 60 * 10000000 % 0x100000000)
      jg <файл старше 3 дней>  
      /* иначе файл младше 3 дней */
    Ответ написан
    2 комментария
  • Почему не получается открыть файл?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    invoke CreateFile, addr [edi].lpstrFile, GENERIC_READ,

    addr [edi].lpstrFile выглядит неправильно. Должно быть либо [edi].lpstrFile (значение указателя, а не его адрес), либо offset buf.
    Ответ написан
  • Перенести ветку мастер в другой репозиторий?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Если master который был в новой репе не нужен, то следующих команд должно быть достаточно:
    git remote add new <url_new_repo>
    git push new +master
    Ответ написан
    3 комментария
  • Почему не собирается EFI application?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    пишет, что не может найти "efi.h", хотя он есть в папке inc из Makefile

    что такое "папка inc из Makefile"? Если ты имеешь в виду переменную inc определённую в 7й строке, то ты её нигде не использовал, а сами по себе переменные с произвольными именами в Makefile ничего не значат.

    gcc -fshort-wchar -I -I/ -I/usr/include -O2 -Wall -fpic -DEFI_FUNCTION_WRAPPER -ffreestanding -nostdlib -c main.c -o main.o
    main.c:1:10: фатальная ошибка: efi.h: Нет такого файла или каталога

    смотри: нигде в списке -I ты не указал своего каталога inc, как по-твоему компилятор должен понять, что efi.h нужно там искать?

    -I$(EFIINC)

    В твоём Makefile не определена переменная EFIINC, откуда ты ожидаешь что она возьмётся?

    Судя по содержимому Makefile стоит заменить имя inc на EFIINC, lib на EFILIB, crtobj на CRTOBJ и т. д.
    Ответ написан
  • Как указать в исполняемом файле абсолютный путь до него самого?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Есть ли возможность из файла узнать его (файла) местоположение?

    readlink -f "$0" для исполняемого скрипта или readlink -f "$BASH_SOURCE" для скрипта загружаемого через source.
    Ответ написан
    2 комментария
  • Что значит этот код?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    что значит код

    ubfx r0, r0, #1, #1 -- извлечь битовое поле шириной 1 бит (правая единица) начиная с бита №1 (левая единица) из регистра r0 (правый r0) и поместить результат в r0 (левый r0).
    bx lr -- перейти по адресу в регистре lr, обычно это возврат из подпрограммы.
    Семантика опкодов легко гуглится по названию опкода и названию архитектуры процессора.

    какая между ними разница

    ubfx r0, r0, #1, #1
    ubfx r0, r0, #2, #1
    теперь, когда ты знаешь, что это за опкод, ты можешь понять сам, что они извлекают битовое поле начиная с разных битовых позиций.

    что я делаю не так

    ты не написал, что конкретно ты делаешь: что и где меняешь и как проверяешь результат.
    Ответ написан
    3 комментария
  • Как изменить существующее прерывание биос?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Вот, что я попытался сделать:
    push word 0
      pop es
      mov bx, 0x11*2+0xF000
      mov word [es:bx], int10-$$


    Расскажи немного словами, что ты имел в виду когда писал это?

    Я пытался гуглить, всю ночь потратил, …
    проблема в отсутствии информации


    Вот это нашёл? https://ru.wikipedia.org/wiki/Таблица_векторов_пре...

    Самое важное для тебя и полностью достаточное для реализации твоей задачи предложение из этой статьи:
    В микропроцессорах Intel 8086/80186 таблица векторов прерываний расположена в первом килобайте памяти начиная с адреса 0000:0000 и содержит 256 векторов прерываний в формате сегмент:смещение.


    boot:
      push word 0
      pop es
      mov bx, 0x11*4
      mov word [es:bx + 2], cs
      mov word [es:bx], int10
    Ответ написан
  • Что происходит во время прерывания в многопоточной среде? Или прерывания посреди прерывания?

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

    Прерывания не знают. Это работа ОС -- организовать информацию так, чтобы при получении прерывания разобраться, откуда оно, зачем, и что с ним делать.

    Прерывание в коде int 21h и прочие Это какое?

    Любое прерывание инициируемое инструкцией int -- программное. В отличие от прерывания, инициируемого уровнем или фронтом сигнала подключённого к контроллеру прерываний.

    Вообще, кажется, если понять, что программные прерывания на x86 используются просто как удобный способ вызывать функции ядра, т.е. делать системные вызовы, то путаницы должно стать меньше. Не думай о них как о прерываниях, думай о них просто как о вызовах функций ядра. Ядро делает всё для того, чтобы для приложения это именно так и выглядело.

    выполнение прерывания std::cin>>line; Может и сутки длиться.

    Системного вызова. std::cin >>line в конце концов превращается в системный вызов read.

    Вот как по пунктам для этой команды. (С условием что есть еще 1 поток жаждущий ЦП).

    Можно запустить такую программу, узнать её PID, выполнить где-нибудь cat /proc/<PID>/stack и увидеть следующую картину:
    [<0>] wait_woken+0x67/0x80
    [<0>] n_tty_read+0x426/0x5a0
    [<0>] tty_read+0x135/0x240
    [<0>] new_sync_read+0x115/0x1a0
    [<0>] vfs_read+0xf4/0x180
    [<0>] ksys_read+0x5f/0xe0
    [<0>] do_syscall_64+0x33/0x80
    [<0>] entry_SYSCALL_64_after_hwframe+0x44/0xa9

    Т.е. поток выполнил системный вызов (ksys_read), зашёл в VFS, добрался до функции чтения в драйвере терминала (tty_read) и перешёл в состояние ожидания в глубине этой функции (wait_woken). Когда драйвер терминала получит данные для программы, он разбудит её поток и системный вызов завершится. До тех пор этот поток будет не готов к выполнению и скедулер ОС просто не будет выделять ему время.

    Мне кажется, что тебе было бы полезно прочитать вторую и третью книжки (Understanding the Linux Kernel и Linux Kernel Developmen) из моего списка.
    Ответ написан
    Комментировать
  • Как происходит доступ к эл. массива на уровне ядра? Malloc выделяет непрерывную физическую память?

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

    Так же как и на уровне приложения -- через трансляцию виртуального адреса в физический.

    Например массив Int* arr = new int[1024*1024*1024] он как храниться?

    Если мы для определённости возьмём linux, то у ядра есть несколько разных способов выделения памяти, в зависимости от того, для чего эта память выделяется. Есть наиболее простой и стандартный kmalloc который выделяет память непрерывную как виртуально так и физически. Обычно этим механизмом нельзя выделить большой непрерывный кусок. Есть vmalloc, который выделяет непрерывную виртуально, но возможно прерывную физически память. Есть get_free_pages который выделяет непрерывные страницы физической памяти, возможно, не отображаемые ни в какие виртуальные адреса. Есть Contiguous Memory Allocator который при старте системы резервирует кусок непрерывной физической памяти и может аллоцировать оттуда куски по запросу.
    Важный момент состоит в том, что аллокации делаемые ядром linux через упомянутые интерфейсы всегда обеспечиваются физической памятью, у памяти ядра нет пейджинга.

    А физическая, для массива то же? Ведь, так будет доступ намного быстрее?

    Почему быстрее? С точки зрения процессора всё равно будет трансляция виртуального адреса в физический, если повезёт -- попадание в TLB, если не повезёт -- ходить по каталогам и таблицам страниц в памяти.

    получается эмулятор каждый адрес вычислять что ли?

    Простой эмулятор -- да, наверно. Умный эмулятор может кешировать эту информацию, например именно это свойство даёт QEMU большую часть его Q.
    Ответ написан
    Комментировать
  • Зачем нужно выравнивание памяти? Точнее, почему процессор обращается 2 раза к невыравниным данным?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Для процессора x86 с word 32bit. Как будут выполняться fetch?
    Хочу ответ в таком формате.

    Что мешает взять спецификацию на процессор и почитать, например, раздел 5.3.6?

    почему процессор обращается 2 раза к невыравненным данным?

    Если посмотреть на схему i386 на первой же странице документа по ссылке выше, то можно увидеть, что шина адреса процессора имеет линии A2 - A31. Линий A0 и A1 тупо вообще нет, физически.
    Ответ написан
    Комментировать
  • Как решить ошибку сборки bashdb?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Please specify the compatibility level in debian/compat
    or via Build-Depends: debhelper-compat (= X)

    Искал в тексте упоминания debhelper-compat, но не нашел.

    Насколько я понял этот документ, рекомендуется указывать зависимость от debhelper-compat вместо зависимости от debhelper. Т.е. надо самому написать
    Build-Depends: debhelper-compat (= 13), texi2html, texinfo
    Ответ написан
    Комментировать
  • Почему не выводятся не корректные результаты в квадратном уравнении?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему выводятся некорректные результаты в квадратном уравнении?
    double discriminant = (b * 2) - 4 * (a * c);

    Потому что в этом месте должно быть не b * 2, а b2
    Ответ написан
    1 комментарий
  • Почему для счётчиков не используют беззнаковые (unsigned) числа?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Часто вижу в коде на C++ и C#, что для счётчиков … используют int, а не uint/unsigned int.
    Почему праграмисты делают это?

    Я слышал следующую теорию, почему это имеет смысл в С++: потому что значение знакового типа в корректно написанном коде не переполняется. (А если таки случилось переполнение, то это UB и всё уже не важно). Поэтому если счётчик имеет знаковый тип и с ним на каждой итерации происходит, например, инкремент, то значение счётчика только увеличивается. Это, в свою очередь, даёт дополнительные возможности для оптимизации. Беззнаковый счётчик инкрементируемый на каждой итерации может внезапно обнулиться, это может быть легальным поведением программы на которое рассчитывает программист.

    А почему они фактически используют int -- наверняка потому что никакой практической разницы не видно, а буков нужно меньше.
    Ответ написан
    2 комментария
  • Как передать двумерный массив функции?

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

    https://qna.habr.com/answer?answer_id=513953#answe...
    Ответ написан
    Комментировать
  • Запуск python скрипта из bash. No such file or directory. Как это решить?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    "$str2$str1"
    '/usr/bin/python3 /opt/uccx-stats/uccx_parse.py /opt/uccx-stats/_uccx_csqstats.txt "FCCPS-CSQ - loggedinagents"'

    подскажите, как это победить

    убрать кавычки там где они не нужны, добавить кавычки там, где они нужны:
    #!/bin/bash
    set -x
    #Запуск скрипта в формате ./csqstats CSQ_name  param
    str1="$1 - $2"
    str2="/usr/bin/python3 /opt/uccx-stats/uccx_parse.py /opt/uccx-stats/_uccx_csqstats.txt"
    $str2 "$str1"
    Ответ написан
    Комментировать
  • Почему биты в регистре архитектуры AVR заносяться именно посредством сдвига 1 на этот бит влево?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    почему нельзя занести этот бит в регистр без сдвига, зачем это придумано
    UCSRA |= (1<<U2X);

    В заголовочных файлах U2X определён как "номер бита U2X в регистре UCSRA", т.е. 1.
    Если бы U2X был определён как "битовая маска поля U2X в регистре UCSRA" (т.е. 2), то все бы писали UCSRA |= U2X;. В ассемблерном коде avr оба эти варианта превратятся в инструкцию sbi UCSRA, 1, устанавливающую бит в регистре по номеру.

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

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

    Потому что современные ОС делают это намеренно, чтобы затруднить эксплуатацию уязвимостей в ПО. Это называется ASLR: address space layout randomization. Обычно есть способ отключить ASLR глобально либо для отлаживаемых программ, чтобы добиться воспроизводимости результатов.
    Так, например, в linux это делается глобально с помощью файла /proc/sys/kernel/randomize_va_space либо командой setarch -R для одного конкретного процесса. Отладчик gdb по умолчанию отключает ASLR для отлаживаемых программ.
    Ответ написан
    3 комментария
  • Какой тип виртуальной памяти Сегментная или Страничная, сейчас используется? Как утроена виртуальная память?

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

    На виндовс, icore 5 процессоре вот сейчас, какой тип памяти работает. И какой тип виртуальной памяти на Risc 5 архитектурах.

    Забудь про сегментную организацию, она есть только в семействе x86, была сильно урезана в x86_64 и в современных ОС почти не используется.

    Вот запускается программа. Что происходит. Типа создается процесс, в MMU в таблице страниц генерируется номер страницы PID>>24 + 0x4000000h адрес примерно. И заноситься в таблицу (https://ru.bmstu.wiki/MMU_(Memory_Management_Unit) ) Создаются типа страницы для данных. Окей

    Это какое-то странное описание, особенно часть PID>>24 + 0x4000000h, это вообще что?
    Если программа получает новое адресное пространство, то оно изначально пустое, программа ни с кем его не делит. Есть вот такая книжка про организацию памяти в linux: https://pdos.csail.mit.edu/~sbw/links/gorman_book.pdf Рекомендую ознакомиться с главой 4.

    как программа вообще может в такой системе вызвать функцию из внешней библиотеки

    первым делом программа загружает внешнюю библиотеку в своё адресное пространство. Дальше уже понятно?

    Что за таблица дескрипторов. Где она находиться.

    Находится где-то в физической памяти. Определяет свойства, размеры сегментов и в какие линейные адреса преобразуются логические адреса внутри этих сегментов. Если ты прочитал про линейные адреса эта часть должна тебе быть понятна. В современных ОС все процессы используют один и тот же селектор для кода и один и тот же селектор для данных, а логические адреса cs:0 ds:0 es:0 и ss:0 транслируется в линейный адрес 0. Это называется "плоская модель памяти".

    Как связана с таблицей страниц?

    Никак. Совершенно ортогональная структура, может работать даже когда страничная адресация выключена.

    Что в конечном итоге храниться TLB буфере????

    Мэппинг "линейный адрес" -> "физический адрес".
    Ответ написан