WedX - журнал о программировании и компьютерных науках

Изменить регистр букв (сборка x86)

Я новичок в сборке и работаю в своей лаборатории для класса сборки. В этой части лабораторной работы мне нужно преобразовать строки в их противоположные заглавные буквы. Так, например:

Если задана строка

Дональд

он должен вернуться

ТЕДОНАЛЬД

Там могут быть точки или другие специальные символы, и в этом случае я бы оставил их в покое. Мне также не разрешено использовать 32-битные регистры. Я должен использовать только 8-битную версию регистров общего назначения x86.

Пока у меня это:

void changeCase(char *string) 
{
  __asm
  {
    // BEGIN YOUR CODE HERE

    mov eax, string; // move the string into eax
    mov ecx, 0; // ecx will be counter

  BEGIN_LOOP:
    cmp byte ptr[eax + ecx * 1], 0;
    je END;

    mov al, byte ptr[eax + ecx * 1]; // get the value of the current counter

    cmp al, 65; // compare first char with A
    jl NEXT_INDEX;

    cmp al, 91;
    jl UPPER_CASE;

    cmp al, 97;
    jl NEXT_INDEX;

    cmp al, 123;
    jl LOWER_CASE;

    jmp NEXT_INDEX;

  UPPER_CASE: // if upper case, make it lower case then go to next index
    add al, 32;
    mov byte ptr[eax + ecx * 1], al;
    jmp NEXT_INDEX;
  LOWER_CASE: // if lower case, make it upper case then go to next index
    sub al, 32;
    mov byte ptr[eax + ecx * 1], al;
    jmp NEXT_INDEX;
  NEXT_INDEX:
    inc ecx;
    jmp BEGIN_LOOP;
  END:
    // END YOUR CODE HERE
  }
}
16.03.2017

  • Вы не можете ожидать, что люди будут кодировать это или писать учебник для вас; сайт не об этом. Начните, а затем отправьте сообщение, когда у вас возникнет конкретный вопрос. Если вы не знаете, с чего начать, вам нужна помощь учителя. 17.03.2017
  • Упс, снова отредактировал пост с моим кодом 17.03.2017
  • Напомним, что бит 5 (шестой бит) — это бит регистра в 7-битном коде ASCII. Вам нужно только изменить этот бит, чтобы повлиять на регистр. Вы можете использовать or или xor в своих интересах. 17.03.2017
  • А твоя проблема? (тот код выглядит на самом деле на удивление солидным для новичка, он не решает задачу полностью, но то, что он делает, он делает нормально, так как вы можете легко проверить в отладчике самостоятельно... и тогда вы, вероятно, сможете лучше сформулировать свою проблему ) 17.03.2017
  • Извините, это выглядело как типичный пост с домашним заданием. Рад видеть, что это не так. 17.03.2017
  • Однако вам все равно нужно сказать, чего вы хотите. Это довольно широко, как есть. С какой проблемой вы столкнулись? 17.03.2017
  • @Carcigenicate Visual Studios сообщает мне, что моя функция неверна. Например, при вводе TheDonald я все равно получаю TheDonald вместо tHEdONALD. Итак, я прав, предполагая, что неправильно храню данные в своем реестре? 17.03.2017
  • Редактировать: я получил правильный ответ после переключения всех моих регистров AL на BL. В чем разница между регистрами AL и BL? 17.03.2017
  • @dppham1: Ты пытаешься нас разыграть? Ответ на ваш вопрос относительно [...]различия между регистрами AL и BL заключается в том, что это разные регистры. Задавание этого вопроса — явный показатель того, что вы не понимаете, о чем этот — ваш собственный — вопрос. 17.03.2017
  • Я не заметил, как вы перезаписали al, уничтожая указатель eax, но я считаю, что вам не следует запускать сборку, вы должны выполнять ее в отладчике, по одной инструкции за раз и проверяя все. Таким образом, вы, вероятно, рано заметите, что внезапно символы строки извлекаются из совершенно другой области памяти, а затем перезапустите и обратите внимание на eax ecx, когда она будет изменена, это даст вам хороший намек. Тем не менее, если вы раньше не знали, что al является лишь частью eax, вам, вероятно, следует немного больше изучить какой-нибудь учебник/книгу, прежде чем писать код. 17.03.2017

Ответы:


1

Проблема в вашем коде заключается в том, что вы используете al и eax для двух разных целей.
al является частью eax. Таким образом, если вы измените al, вы фактически измените младший значащий байт eax.
Поскольку вы используете eax в качестве базового указателя, вы не должны манипулировать им, вместо этого используйте свободный регистр, такой как edx, и его младший байт dl для выполнения манипуляции с прописными буквами.
Если вы манипулируете al, то указатель eax будет указывать повсюду, что приведет к нежелательным результатам.

Глядя глубже в код, нет необходимости использовать как ecx, так и eax в качестве указателей, достаточно одного из них, потому что вы можете сказать, что находитесь в конце строки, прочитав ее завершающий нулевой байт.

Вы можете легко оптимизировать этот код следующим образом:

__asm{
    // BEGIN YOUR CODE HERE

    mov eax, string; // move the string into eax

BEGIN_LOOP:
    mov dl, byte ptr[eax]; //get the current char.
    test dl,dl             //is it the terminating zero?
    jz END                 //yes, we're done

    cmp dl, 'A'; // compare first char with A
    jl NEXT_INDEX;         //smaller than A, skip

    cmp dl, 'z'; //compare char with z
    jg NEXT_INDEX;        //bigger than z, skip

    xor dl,32              //'a' = 'A' + 32 and 'A' = 'a' - 32 use xor to filp that bit
    cmp dl,'z'             //Make sure we don't flip '[]\^_'
    cmovle [eax],dl        //only write when result within bounds
NEXT_INDEX:                //write back the flipped char.
    inc eax;               //next char.
    jmp BEGIN_LOOP;
END:
}

Есть много способов его дальнейшей оптимизации, но я не хочу слишком усложнять проблему.
Обратите внимание, что в программировании x86_32 eax, ecx и edx считаются изменчивыми на большинстве платформ и некоторых других регистров. может не. Поэтому лучше использовать только эти регистры, если вам это сойдет с рук.
Если вы используете другие регистры, вы должны push затем при запуске подпрограммы и pop их перед выходом из подпрограммы.

17.03.2017
  • Этот код также перевернет [\]^_`, поэтому ему нужен еще один тест (после xor dl,32 перед записью использование cmp dl,'z' снова исправит это). И я бы предложил использовать cmp dl,'A' и cmp dl,'z', чтобы было очевидно, что тестируется. И переходы условий неверны, подойдет либо jb + ja, либо jl + jg. (и вы заставили меня почувствовать себя ржавым, я не заметил очевидной проблемы mov al,[eax...] исходного поста :)) 17.03.2017
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]