-1

ステートメント を変換しようとしていますif(isalpha(c))。ここcで、 は char 変数で、C++ から MIPS アセンブリに変換しようとしています。グーグルで検索してみましたが、答えが見つかりませんでした。誰にもアイデアはありますか?御時間ありがとうございます。

4

1 に答える 1

1

I'm just going to demonstrate one possible way, which is not efficient or "cool", but it's simple.

So, you want an equivalent of this C block:

if (isalpha(c))
{
    /* Do stuff... */
}

Which is like this, considering how isalpha() works:

if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))
{
    /* Do stuff... */
}

But there are no "block" structures in assembly. Everything is a jump (or a goto in C, which you should never use.) So, to get closer to the assembly version, we might modify our C code to use a jump:

if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
    goto AfterStuff;

/* Do stuff... */

AfterStuff:

Note that we are jumping over the "Do stuff" part if the reverse of our condition was true. Now, assuming we know that 'A' < 'Z' < 'a' < 'z' (the ASCII codes are, respectively: 65, 90, 97, 122,) then we can rewrite the above code like this:

if (c < 65)
    goto AfterStuff;
if (c <= 90)
    goto DoStuff;
if (c < 97)
    goto AfterStuff;
if (c > 122)
    goto AfterStuff;

DoStuff:
/* Do stuff... */

AfterStuff:

Note that if c is less than 'A', we jump after the stuff. But if after comparing c and 'A', we find out that c is not only greater or equal to 'A' (because we didn't jump away,) but it's also less than or equal to 'Z', we jump directly to the "stuff" and don't check anything else. Also, the operands of the last blt instruction are reversed.

The assembly gets a little complicated, because we have to load the required immediates into registers and whatnot. Here's the code:

  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:

I believe the above works, but I absolutely can't be sure. It has been more than a decade since I wrote any MIPS assembly code (or any other code for a MIPS) and I was never very proficient anyways.

于 2013-04-21T01:48:53.067 に答える