С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

Нетривиальный тривиальный калькулятор - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ GPS и поиск кратчайшего пути http://www.cyberforum.ru/cpp/thread1235442.html
Здравствуйте, столкнулся с такой проблемой, хочу сделать GPS, простенькую программу, даже можно сказать картинку, которая бы позволяла найти наименьший путь от одной точки до другой. Подробнее:...
C++ Библиотеки для работы с джейсоном, не требующие dll Судя по всему, jsoncpp что я пытался использовать обязует таскать с собой лишнюю длл, что меня совершенно не устраивает. Можно как-нибудь это поправить? Код-то я уже написал=\ Ну а если нет, то... http://www.cyberforum.ru/cpp/thread1235319.html
C++ Отслеживание нажатий клавиш, когда окно программы не в фокусе
Доброго времени суток, цель - написать программу, выполняющую код функции (напишу самостоятельно) по нажатию клавиши. Функций должно быть несколько, соответственно и клавиш тоже. При этом программа...
Браузер, как предотвратить открытие другого браузера при переходе по ссылке? C++
Лепил браузер с нуля. Такой простенький для практики. Все главное вроде сделал, но обнаружил такой баг. При переходе по ссылке открывает эксплорер. То есть если начать искать что либо в гугле, а...
C++ Интересный пример оптимизации http://www.cyberforum.ru/cpp/thread1233361.html
Привет! Копаясь в OpenJDK наткнулся на довольно интересный подход (оптимизацию). Решил поделиться, кому-то может быть полезно в плане общего развития, а кому-то может быть просто любопытно. Код,...
C++ Алгоритм для обработки данных частотного анализа Честно говоря я сомневаюсь, что писать нужно сюда, но к экспертам меня не пускают)) Сам я далеко не эксперт! Очень надеюсь на ваше помощь, думаю что вы мне сможете помочь. Создаю устройство,... подробнее

Показать сообщение отдельно
Kastaneda
Jesus loves me
Эксперт С++
4697 / 2901 / 238
Регистрация: 12.12.2009
Сообщений: 7,389
Записей в блоге: 2
Завершенные тесты: 1

Нетривиальный тривиальный калькулятор - C++

28.07.2014, 21:57. Просмотров 565. Ответов 4
Метки (Все метки)

Привет!
Ковырясь в OpenJDK разобрался как генерится/исполняется ассемблерный код в рантайме. Решил поделиться увиденным подходом, написал калькулятор, который часто здесь просят студенты (ввести 5 + 5, напечатать ответ).
Обычно это выглядит так
C++
1
2
3
4
5
switch (op) {
case '+': return a + b;
case '-': return a -b;
// etc
}
а вот как это выглядит с генерацией кода в рантайме (только linux x64)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/mman.h>
 
 
int main()
{
    int a, b;
    char op;
    std::cin >> a >> op >> b;
 
    const int page_size = sysconf(_SC_PAGESIZE);
    unsigned char *buffer = new unsigned char[page_size * 2];    
    unsigned char *page_start = (unsigned char*)(((long)buffer) & ~(page_size - 1)); // необходимое выравнивание
    
    unsigned char opcodes[3][128] = {
      {0x48, 0x01, 0xF7, 0x48, 0x89, 0xF8, 0xC3},
      {0x48, 0x29, 0xF7, 0x48, 0x89, 0xF8, 0xC3}, 
      {0x48, 0x89, 0xF8, 0xF7, 0xE6, 0xC3}, 
    };
    
    int op_pos = std::string("+-*").find(op);
    memcpy(page_start, &opcodes[op_pos][0], 128);
 
    if (mprotect(page_start, page_size, PROT_EXEC)) {
        std::cout << "mprotect error1" << std::endl;
        return 1;
    }
    
    int res = ((int (*)(int, int))page_start)(a, b);
    std::cout << a << " " << op << " " << b << " = " << res << std::endl;
    
    return 0;
}
писал на коленке, поэтому не пинайте за константы 3, 128, etc. Может для кого-то это не будет новым, но многим, думаю, будет интересно.

P.S. допустимые арифметические операции +, - и *. Деление было уже влом делать Никаких проверок ввода, как видите, нет.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.