Arhn - архитектура программирования

Как использовать строковые матрицы во встроенной сборке С++

Мне дали задание транслитерировать с кириллицы на латиницу с помощью встроенного MASM. Я написал следующий код, который теперь может обрабатывать только простые звуки, такие как «а», «б» и так далее.

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <clocale>
#include <Windows.h>

using namespace std;

int main()
{
    SetConsoleCP(1251);

    SetConsoleOutputCP(1251);

    char map[33][4] = { "a",
    "b"
    , "v"
    , "g"
    , "d"
    , "e"
    , "z"
    , "z"
    , "i"
    , "i"
    , "k"
    , "l"
    , "m"
    , "n"
    , "o"
    , "p"
    , "r"
    , "s"
    , "t"
    , "u"
    , "f"
    , "h"
    , "c"
    , "tch"
    , "sh"
    , "sch"
    , ""
    , "yy"
    , ""
    , "ae"
    , "yu"
    , "ya" 
    };

    char str_out[160];
    char str_in[80];
    cin.getline(str_in, 80);

    _asm
    {

        lea esi, str_in;
        lea edi, str_out;

    Process:
        lods 
        cmp al, '\0';

        je End_String;
        cmp al, 223;
        jb Write_Symbol;

        // russian а stands for == 224

    translit:
        mov ebx, esi;
        mov ecx, edi;
        xor edi, edi;
        lea esi, map;
        movzx edi, al;
        sub edi, 224
        mov al, [esi + edi*4]; // **loads only first character**
        mov esi, ebx;
        mov edi, ecx;
        jmp write_symbol;

    Write_Symbol:
        stos;
        jmp Process;

    End_String:
        stos;

    }

    cout << str_out << endl;

    system("pause");

    return 0;
}

Но проблема начинается, когда мне нужно иметь дело со сложными звуками, такими как «тчи», «ча» и т. Д. В основном задача состоит в том, чтобы загрузить начало соответствующей строки с помощью регистров esi и edi и вызвать систему, чтобы напечатать мне строку, но я не Не понимаю, как это сделать, как загрузить адрес такой строки и вызвать системный вызов.


  • Вы можете выполнить загрузку dword, так как знаете, что у вас есть 4 байта. Вы можете bsr и разделить на 8 с округлением вверх (используя сложение и сдвиг вправо), чтобы узнать, где находится старший ненулевой байт, т.е. сколько байтов фактически скопировать в целевой буфер. (На самом деле просто сделайте 4-байтовое хранилище и увеличьте указатель на это число; 1-байтовые выходные данные будут перекрываться на 3, но это нормально.) 30.11.2020

Ответы:


1

Итак, благодаря @Peter Cordes я решил свою задачу:

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <clocale>
#include <Windows.h>

using namespace std;
char map[33][8] = { 
    "a...",
    "b..."
    , "v..."
    , "g..."
    , "d..."
    , "e..."
    , "z..."
    , "z..."
    , "i..."
    , "i..."
    , "k..."
    , "l..."
    , "m..."
    , "n..."
    , "o..."
    , "p..."
    , "r..."
    , "s..."
    , "t..."
    , "u..."
    , "f..."
    , "h..."
    , "c..."
    , "tch."
    , "sh.."
    , "sch."
    , "...."
    , "yy.."
    , "...."
    , "ae.."
    , "yu.."
    , "ya.."
};


int main()
{
    SetConsoleCP(1251);

    SetConsoleOutputCP(1251);

    cout << &map << "\n";

    char str_out[160];
    char str_in[80];
    cin.getline(str_in, 80);

    int len = 0;

    _asm
    {
        lea esi, str_in;
        lea edi, str_out;

    Process:
        xor eax, eax;
        lodsb
        cmp al, '\0';
        je End_String;
        cmp al, 223;
        jb Write_Symbol;

        // я == 255

    translit:
        mov ebx, esi;
        mov ecx, edi;
        xor edi, edi;
        lea esi, map;
        movzx edi, al;
        sub edi, 224;

        mov eax, dword ptr [esi + edi*8];
        mov esi, ebx;
        mov edi, ecx;
        add len, 4;
        stosd;
        jmp Process;

    Write_Symbol:
        add len, 1;
        stosb;
        jmp Process;

    End_String:
        stosb;

    }

    str_out[len] = '\0';

    for (int i = 0; i < len; i++) {
        if (str_out[i] != '.') {
            cout << str_out[i];
        }
    }
    cout << "\n";

    system("pause");

    return 0;
}
30.11.2020
  • Это ужасно неэффективно (много 1-байтовых вызовов cout<<) и уничтожает любые '.' символы во входных данных. Как я уже сказал, пусть ассемблер вычисляет, на сколько байтов увеличить указатель, вместо того, чтобы делать это позже в C, чтобы пропустить заполнение. Вам также не нужен map[33][8], он все еще может быть map[33][4] с неявным заполнением нулями до 4 для более коротких инициализаторов строк. 01.12.2020
  • Как я уже сказал, bsr будет хорошим способом узнать, сколько символов содержится в загруженном вами двойном слове, если они дополнены нулями, как в исходном вопросе. 01.12.2020
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..