Я пытаюсь перевести заявление if(isalpha(c))
, где c
переменная типа char, от C ++ до сборки MIPS Я пытался гуглить, но не смог найти ответ. У кого-нибудь есть идеи? Спасибо за ваше время.
Я просто собираюсь продемонстрировать один из возможных способов, который не эффективен или «крут», но он прост.
Итак, вы хотите эквивалент этого блока C:
if (isalpha(c))
{
/* Do stuff... */
}
Что, как это, учитывая, как isalpha()
работает:
if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))
{
/* Do stuff... */
}
Но в сборке нет «блочных» конструкций. Все это Прыгать (или goto
в C, который вы должны никогда использовать.) Итак, чтобы приблизиться к версии сборки, мы могли бы изменить наш код C, чтобы использовать переход:
if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
goto AfterStuff;
/* Do stuff... */
AfterStuff:
Обратите внимание, что мы перепрыгиваем через часть «Делать вещи», если задний ход нашего состояния было правдой.
Теперь, если мы знаем, что 'A'
< 'Z'
< 'a'
< 'z'
(ASCII-коды, соответственно: 65, 90, 97, 122,) тогда мы можем переписать приведенный выше код следующим образом:
if (c < 65)
goto AfterStuff;
if (c <= 90)
goto DoStuff;
if (c < 97)
goto AfterStuff;
if (c > 122)
goto AfterStuff;
DoStuff:
/* Do stuff... */
AfterStuff:
Обратите внимание, что если c
меньше, чем «А», мы прыгаем за вещи. Но если после сравнения c и ‘A’ мы обнаружим, что c не только больше или равно ‘A’ (потому что мы не прыгали, но также и меньше или равно ‘Z’), мы прыгаем напрямую на «вещи» и не проверяйте ничего больше. Также операнды последнего blt
инструкция полностью изменена
Сборка немного усложняется, потому что мы должны загрузить необходимые немедленные элементы в регистры и еще много чего. Вот код:
lb $t0, ($s0) # assuming address of c is in s0 register
addi $t1, $zero, 65 # set t1 = 'A'
blt $t0, $t1, AfterStuff # if (c < 'A') goto AfterStuff
addi $t1, $zero, 90 # set t1 = 'Z'
ble $t0, $t1, DoStuff # if (c <= 'Z') goto DoStuff
addi $t1, $zero, 97 # set t1 = 'a'
blt $t0, $t1, AfterStuff # if (c < 'a') goto AfterStuff
addi $t1, $zero, 122 # set t1 = 'z'
blt $t1, $t0, AfterStuff # if ('z' < c) goto AfterStuff
DoStuff:
# Do whatever you want to do
AfterStuff:
Я верю, что вышесказанное работает, но я абсолютно не уверен. Прошло уже более десяти лет с тех пор, как я написал какой-либо ассемблерный код MIPS (или любой другой код для MIPS), и в любом случае я никогда не был очень опытным.
Других решений пока нет …