【问题标题】:Mips string character manipulation without lb and an offset没有 lb 和偏移量的 Mips 字符串字符操作
【发布时间】:2021-06-10 09:24:58
【问题描述】:

我是 MIPS 的新手,我试图弄清楚如何在没有 lb/sb 和偏移量的情况下操作字符串中的单个字符。我已经知道如何通过加载字符串的地址并通过增加偏移量来循环执行此操作,但是如果我只有一个字符寄存器怎么办?假设我有一个包含几个字符的寄存器。我怎样才能访问每个字符并将其设为大写。我知道我必须将字符减去 32 才能使其大写,但是我在遍历字符时遇到了麻烦。如果我转移,我最终不会失去角色吗?像这样:

add $t0, $t0, 1
subi $t0, $t0, 32
add $t0, $t0, 1

等等。遍历每个字符的正确方法是什么?

【问题讨论】:

  • 如果你事先知道每个单词都有英文字符(每个字节要么大写要么小写ASCII码)或空值,你可以andi0xDFDFDFDF使每个小写字母都大写。只需查看 ASCII 表即可了解模式。

标签: assembly mips


【解决方案1】:

如果不使用加载操作,就无法访​​问内存。如果您想在字符串上使用字大小的加载操作 (lw),您将受到对这些指令使用对齐地址的要求的限制(在 MIPS 上 - 其他处理器将以最小的性能损失执行未对齐的访问) .

如果我们可以依赖从对齐边界开始的所有字符串,并且长度始终是 4 字节的倍数,那么处理对齐要求就不那么难了。移除长度限制(4 的倍数)会增加复杂性,就像移除初始对齐限制(4 的倍数)一样。对于通用解决方案,这两个对齐问题都需要解决,这意味着区分多个案例以使用字大小的操作。


如果您在一个寄存器中确实有 4 个字符,并且您想要调整(即大写)每个不同的 4 个字节,那么您几乎必须单独查看它们。确实没有办法立即计算要添加的值,该值将大写每个字节。

需要明确的是,对于任何给定的 4 个字符的 4 字节值,只有一个 32 位调整值可以添加以 4 个字节中的每一个都大写一次——但是有 16 个可能的这样的值,并且没有简单的方法来确定 16 个中的哪一个是任何给定的 4 字节值的正确值。 所以,你会必须提取每个字节并单独考虑,这几乎与直接使用lb/sb 一样有效。

【讨论】:

  • 如果您知道所有字符都是字母,实际上很容易将它们全部强制为大写:并且使用~0x20202020 清除每个字节中的大写位。 What is the idea behind ^= 32, that converts lowercase letters to upper and vice versa?你当然不想addsubtract,但你谈论它就像你无能为力。
  • 有条件地仅对字母字符执行此操作更难,并且仅使用 4 字节寄存器可能不值得。 SWAR (SIMD Within A Register) 加/减,同时阻止元素之间的进位需要更多的屏蔽。但对于 7 位 ASCII 可能是可行的,包括打包的 c -= 'a'c-=25(最大字母索引)来设置或清除备用的最高位。甚至在 MIPS64 上可能值得,您一次可以处理 8 个字节。显然,使用适当的 SIMD 会更容易,例如 SSE2 pcmpgtb 或饱和减法 + 比较;大概 MIPS SIMD 也有类似的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-07
  • 1970-01-01
  • 2019-12-07
  • 1970-01-01
  • 2016-12-22
相关资源
最近更新 更多