测试值是否在两个范围之一内 [英] Testing if a value is within one of two ranges

查看:61
本文介绍了测试值是否在两个范围之一内的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个MIPS程序,该程序仅应使用大写或小写字符作为输入.我的程序使用字符的ASCII值工作.

I am writing a MIPS program that should only works with uppercase or lowercase characters as input. My program works using the ASCII values of the characters.

我需要检查输入中的每个字符是否在65-90(A-Z)或97-122(a-z)的ASCII范围内.如果不在两个范围内,请跳过此字符并重复下一个字符.该怎么办?

I need to check if each character in the input is in the ASCII range of 65-90 (A-Z) or else 97-122 (a-z). If it is not in either of those ranges, skip this character and repeat for the next character. How can this be done?

编辑

这是我刚想出的一个解决方案,但是我敢肯定有一个不太丑陋的方法可以做到这一点?

Here is a solution I just came up with but I'm sure there is a less ugly way to do this?

function:    #increment $t0 to next char of input
             blt $t0, 65, function
             bgt $t0, 122, function
             blt $t0, 91, continue
             bgt $t0, 96, continue
             j   function
continue:    ...
             j   function

推荐答案

无论您做什么,都需要四个分支实例.

No matter what you do, you'll need four branch insts.

我要做的第一件事是在每条指令中添加侧边栏注释.

The first thing I'd do is add sidebar comments to each instruction.

好的注释是任何语言的一部分,但对asm来说是至关重要的.几乎每行都应该有它们.它们解决了算法的逻辑(即什么/为什么").指令本身就是如何".

Good comments are part of any language, but crucial for asm. Virtually every line should have them. They address the logic of your algorithm (i.e. the "what/why"). The instructions themselves are the "how".

请注意,您将十进制数字用于ASCII字符.没有注释,很难遵循逻辑来确定指令是否正确.

Notice that you're using decimal numbers for the ASCII chars. Without comments it's difficult to follow the logic to determine if the instructions are correct.

我会稍微调整一下分组,以将 A-Z 测试保持在一起,而将 a-z 测试保持在一起,而不是将它们混在一起.这可能会稍慢一些,但代码会更直观.

I'd adjust your grouping a bit to keep A-Z tests together and a-z tests together and not intermix them. This might be slightly slower, but the code is more intuitive.

我还做了一个很容易理解的第三版.它使用字符常量代替硬连接的十进制值.

I also did a third version that is very easy to understand. It uses character constants instead of hardwired decimal values.

这是带注释的原件:

 function:
    # increment $t0 to next char of input

    blt     $t0,65,function         # less than 'A'? if yes, loop
    bgt     $t0,122,function        # greater than 'z'? if yes, loop

    blt     $t0,91,continue         # less than or equal to 'Z'? if yes, doit
    bgt     $t0,96,continue         # greater than or equal to 'a'? if yes, doit

    j       function

continue:
    # ...
    j       function


这是重新排序的版本:


Here's the reordered version:

 function:
    # increment $t0 to next char of input

    blt     $t0,65,function         # less than 'A'? if yes, loop
    blt     $t0,91,continue         # less than or equal to 'Z'? if yes, doit

    bgt     $t0,122,function        # greater than 'z'? if yes, loop
    bgt     $t0,96,continue         # greater than or equal to 'a'? if yes, doit

    j       function

continue:
    # ...
    j       function


这是最简单的版本.这是最容易理解的,就我个人而言,我会这样做.它还消除了多余的/多余的 j 指令.

以前的版本必须知道" A-Z 的值低于 a-z .他们可以摆脱",因为ASCII值以十进制"形式硬连线".

The previous versions have to "know" that A-Z is lower in value than a-z. They could "get away" with this because the ASCII values were "hardwired" in decimal.

在C语言中,[不一定]是个好主意(即,您将使用字符常量).mips汇编器允许使用字符常量,因此以下内容实际上是有效的:

In C, that wouldn't [necessarily] be a good idea (i.e. you'd use the character constants). mips assemblers allow character constants, so the following is actually valid:

 function:
    # increment $t0 to next char of input

    blt     $t0,'A',trylower        # less than 'A'? if yes, try lowercase
    ble     $t0,'Z',continue        # less than or equal to 'Z'? if yes, doit

trylower:
    blt     $t0,'a',function        # less than 'a'? if yes, loop
    bgt     $t0,'z',function        # greater than 'z'? if yes, loop

continue:
    # ...
    j       function

有一个古老的格言:在使其变得更快之前就做好它(摘自Brian Kernighan和P.J. Plauger的编程风格元素")

There's an old maxim: Make it right before you make it faster (From "Elements of Programming Style" by Brian Kernighan and P.J. Plauger)

这里是构建查询表的额外版本.预构建它需要花费更多时间,但是实际循环更快.

Here's an extra version that builds a lookup table. It takes a bit more to pre-build it, but the actual loop is faster.

在各种版本中, blt bgt 是伪操作,它们生成 slti bne addi slti bne .因此,我们实际上是在谈论10条指令,而不仅仅是4条.

In the various versions blt and bgt are pseudo ops that generate slti,bne and addi,slti,bne respectively. So, we're really talking about 10 instructions and not just 4.

因此,表构建可能值得进行更简单/更快速的循环.

So, the table build may be worth it to get a simpler/faster loop.

    .data
isalpha:    .space  256

    .text
main:
    la      $s0,isalpha             # get address of lookup table

    li      $t0,-1                  # byte value
    li      $t2,1                   # true value

    # build lookup table
build_loop:
    # increment $t0 to next char of input
    addi    $t0,$t0,1               # advance to next char
    beq     $t0,256,build_done      # over edge? if so, table done

    blt     $t0,'A',build_lower     # less than 'A'? if yes, try lowercase
    ble     $t0,'Z',build_set       # less than or equal to 'Z'? if yes, doit

build_lower:
    blt     $t0,'a',build_loop      # less than 'a'? if yes, loop
    bgt     $t0,'z',build_loop      # greater than 'z'? if yes, loop

build_set:
    addiu   $t1,$s0,$t0             # point to correct array address
    sb      $t2,0($t1)              # mark as a-z, A-Z
    j       build_loop              # try next char

build_done:

function:
    # increment $t0 to next char of input

    addu    $t1,$s0,$t0             # index into lookup table
    lb      $t1,0($t1)              # get lookup table value
    beqz    $t1,function            # is char one we want? if no, loop

continue:
    # ...
    j       function


这是带有预定义查找表的版本:


Here's a version with a predefined lookup table:

    .data
isalpha:
    .byte   0:65
    .byte   1:26
    .byte   0:6
    .byte   1:26
    .byte   0:133

    .text
    la      $s0,isalpha             # get lookup table address

function:
    # increment $t0 to next char of input

    addu    $t1,$s0,$t0             # index into lookup table
    lb      $t1,0($t1)              # get lookup table value
    beqz    $t1,function            # is char one we want? if no, loop

continue:
    # ...
    j       function

这篇关于测试值是否在两个范围之一内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆