Задать вопрос
Ответы пользователя по тегу C
  • Как исправить ошибку "Кадр не находится в модуле" при создании потока?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    "Кадр не находится в модуле". Подскажите с чем это может быть связано
    HANDLE h = CreateThread(
        NULL,
        0,
        factorial(gn),
        NULL,
        NULL,
        NULL
    );

    Третий параметр CreateThread -- указатель на функцию, которая будет запущена в создаваемом потоке. А у тебя записано скорее всего что-то другое. Если ты хотел запустить функцию factorial в потоке, она должна 1) иметь определённый прототип (вот такой), и 2) в функцию CreateThread надо передать её адрес, а не результат её вызова (например, так: CreateThread(NULL, 0, factorial, NULL, NULL, NULL)). 3) если ты сделаешь эти два изменения, тебе прийдётся также переделать передачу параметра в функцию factorial и получение результата её работы.
    Ответ написан
  • Как реализовать _open() для добавления своих потоков ввода-вывода?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почитать про libgloss, понять что надо самому разбирать пути переданные в параметре name и где-то хранить данные о том, что за файл и как был открыт. Понять, как именно ты хочешь "реализовать работу со своими устройствами" и… реализовать её.
    Ответ написан
  • Почему не работает 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
    Как сортировать данные структуры по дате, если дата задаётся символьной строкой?

    Строки вида yyyymmdd можно сортировать с помощью qsort сравнивая их функцией strcmp.
    Ответ написан
    Комментировать
  • Почему при работе с бинарными файлами .exe вызвал срабатывание точки останова СИ?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Первая функция работает, а при вызове второй функции - "срабатывание точки останова" при присвоении переменной fp указателя на поток - при вызове функции fopen(). Помогите разобраться с проблемой не понимаю, где ошибка.

    Вторая функция как-то очень сильно завязана на первую: arr она не инициализирует и считает, что там достаточно места для содержимого файла. Но это всё происходит после заявленной проблемы.
    В первой функции вызовы gets читают строчки неограниченной длины в какие-то поля твоей структуры. Определения структуры ты не привёл, но мой магический шар говорит, что gets вполне может вылезти за пределы полей в которые он читает и поломать кучу. Можно попробовать заменить gets(x) на fgets(x, sizeof(x), stdin).
    Ответ написан
  • Как программа получает ввод?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Здесь нет ни putchar(), ни scanf(), ни тому подобного.

    есть c = getchar().

    ОТКУДА программа получает ввод?

    из стандартного потока ввода, откуда getchar читает символы.
    Ответ написан
    Комментировать
  • Почему память в стеке для auto переменной не резервируется с помощью rsp?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    А почему память не резервируется с помощью rsp? А если произойдет прерывание? Или тут какая-то хитрость?


    Тут какая-то хитрость под названием red zone.
    Ответ написан
    Комментировать
  • Что больше? 1073741024 или 2147483648?

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

    на сегодня уже хватит программирования. Речь о размере объекта (в байтах), а каждый элемент массива int наверняка занимает хотя бы 4 байта.
    Ответ написан
    Комментировать
  • Откуда берется "OK" в виртуальном терминале?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    откуда взялся тот OK?

    пришёл от модема, в ответ на AT-команду.
    Ответ написан
  • Какой тип данных используется для чисел с фиксированной запятой на C?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Какой тип данных используется для чисел с фиксированной запятой на C?

    Нет такого стандартизированного типа данных.

    мне нужно провести вычисления с фиксированной запятой

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

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

    вот тебе цикл, который считает слова в файле fin, не расстраивайся:
    int z = 0;
    
    while (fscanf(fin, "%*s") == 0)
        ++z;
    Ответ написан
    Комментировать
  • Что не так с вложенным циклом?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    На выходе почему-то не выводятся все значения у, а только y=0

    У тебя там getchar() в коде стоит на каждой итерации по y. Ты на Enter-то нажимаешь?
    Ответ написан
    Комментировать
  • Вызов функции C в другом файле. Как реализовать?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Код выглядит нормально. Разбирайся с тем как выполняется сборка проекта. Похоже, что проект не линкуется с main.o
    Ответ написан
    Комментировать
  • Проблема с перестановками строк?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    array[pair[0]][1]=array[pair[1]][i];

    Ошибка здесь. Вместо первой 1 должна быть i.
    Ответ написан
  • Как реализовать на с или assembler асинхронную выборку из RAM?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как реализовать на с или assembler асинхронную выборку из RAM?

    Например так. Это часть реализации memcpy для MIPS. Этот код не выглядит асинхронным, но написан именно так (сначала групповая загрузка в разные регистры, потом изменение базового адреса загрузки, потом групповое сохранение, потом изменение базового адреса сохранения) с рассчётом на то, что процессор сможет, в том числе, перекрыть во времени операции загрузки, арифметики и сохранения данных.
    Ответ написан
    2 комментария
  • Include/header guards зачем?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Зачем нужны header guards если в заголовочных файлах мы пишем только объявление функции?

    Не всегда мы пишем только объявления. Иногда мы там пишем определения, например определяем структуры, или псевдонимы типов (typedef). Повторное определение таких вещей -- ошибка. Тут ты можешь сказать: "но я подключаю хедер в каждый исходник только один раз". Да, пока проект простой можно это отследить. Но когда одни хедеры начинают подключать другие хедеры это становится делать сложнее. header guards упрощают развитие проекта.
    Иногда между хедерами бывают циклические зависимости, header guards позволяют разорвать цикл.
    Ответ написан
    Комментировать
  • Почему при записи в /proc/ система зависает?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    static struct file_operations process_sched_add_module_fops = {
    …
    proc_create(PROC_CONFIG_FILE_NAME,0777,NULL,&process_sched_add_module_fops);

    Я думаю, что это основная ошибка: proc_create принимает указатель на структуру proc_ops, а не на file_operations. Компилятор должен был бы что-нибудь сказать в этом месте, ты не читаешь его предупреждения?

    static ssize_t process_sched_add_module_write(struct file *file, const char *buf, size_t count, loff_t *ppos)

    А здесь ты потерял аннотацию __user у параметра buf. Этот буфер приходит из юзерспейса, по этой причине ты не можешь лезть в него напрямую функцией kstrtol.
    Ответ написан
  • Почему выводится только первое слово из scanf() в printf() в Си?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему?

    Потому что scanf("%s", name) сканирует поле до первого пробельного символа.
    Если ты хочешь строчку до конца строки используй, например, scanf("%[^\n]", name)
    Ответ написан
    5 комментариев
  • Почему этот код работает?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    copy_from_user(ips[i], buffer,256);
    
       	printk(KERN_INFO "ips: %s \n", ips[i]);
       	i++;
    
       	if(strncmp(ips[0],"wh",2)==0){

    почему он работает,

    Во-первых этот код неполный, он использует переменные определённые где-то ещё, от того как именно они определены зависит насколько он "работает".
    Во-вторых, по тому что видно, работает он, скажем, так себе:
    - он печатает строчку принятую из юзерспейса без ограничения длины. Если юзер не поставил 0-терминатор, то напечатает мусор из пространства ядра за нефиг делать.
    - копирование происходит в ips[i], где i увеличивается с каждым вызовом, а анализ всегда смотрит на ips[0].
    - в прототипе функции отсутствует аннотация __user у параметра buffer.

    как его можно переписать, чтобы было удобнее читать?

    Я бы сказал, что его и так удобно читать, особенно если форматирование поправить.
    Ответ написан
    Комментировать