lb指令的奇怪输出

时间:2017-02-15 19:32:17

标签: assembly mips

.data 
 number:.word 3222
.text 
.globl _start
 _start:
      li $v0,1
      la $t0,number
      lb $a0,($t0)
      syscall
      li $v0,10
      syscall

我对MIPS汇编语言完全陌生。我试图得到Label.word 3222的第一个数字,即3,但是输出是150.我只是好奇这150来自哪里,我怎么能得到我想要的值(得到第二和第三位数为孔)

1 个答案:

答案 0 :(得分:2)

word是32位值。 MIPS可以设置为大或小的字节序。

如果您将了解如何将整数值编码为位的最常用方法,使用二进制表示,您将看到单字节(8位)可以包含0到255之间的值。

32位= 4个字节因此可以包含256个 4 值:0 - 4294967295

所以二进制32220000 1100 1001 0110(仅为16位,以免我为高16位写入另外16个零)。

您的目标MIPS平台设置为little-endian模式,即。第一个字节包含8个最低有效位,因此在内存中该数字被编码为位:

address: |   value:
+0       |  1001 0110   (in hexa 0x96, or decimal 150)
+1       |  0000 1100   (0x0C, 12)
+2       |  0000 0000   (0x00, 0)
+3       |  0000 0000   (0x00, 0)

总值为150 * 256 0 + 12 * 256 1 + 0 * 256 2 + 0 * 256 3 = 3222。

要获得该数字的第一个数字,您必须计算它的log 10 以知道哪个是第10个幂,或者从右边开始计算div / mod对10 < sup> 1 ,余数是“ones”数字,商可以用另一个除以10得到“十”,然后“数百”等等,直到你得到零。

总体来说,基数为10(十进制)的数字对于计算机来说非常麻烦,需要大量的实际计算来计算出特定的数字(除非你把它们存储为字符串或者不是二进制编码(例如BCD)) - &gt ;然后很容易得到特定的数字,但你不能使用简单的算术指令,如add,因为那些理解二进制表示。)

另请注意4位组如何形成0到15之间的值,它与1:1匹配十六进制数字0-F,因此从十六进制表示值可以轻松读取特定字节的值(两位=一个字节) )。 3222 = 0x00000C96 = four bytes 0x00, 0x00, 0x0C and 0x96(以小端顺序存储在内存中,即从0x96开始反转)。

对于dec&lt; - &gt;的特定细节。十六进制&lt; - &gt;二进制&lt; - &gt;八进制转换,以及为什么/如何工作只需参考维基百科或一些教程。

只有一个简短的建议:3222不是数字3222,它是数字3222在基数10(十进制)格式中的表示,这是人类常用的。但是价值本身并没有任何格式,它纯粹是抽象的东西。通过将其写为3222或将其称为声音,或者使用其他(六角/二进制)编码,您只会生成真实数学值的“图像”,实际上会因您所需表示的任何缺陷而损坏其属性。 。例如,在十进制格式中,每个整数都有两种表示方式,一种是常见的短3222,另一种是具有无限系列的九个分数3221.9999...(它是相同的数字)。

值的各种计算机编码(特别是浮点值)有其自身的局限性和怪癖,因此您应该了解计算机如何编码值以了解您在计算中使用的内容。所以你后来不会感到惊讶,例如在x86_64的C ++中:(1e40 + 1.0 == 1e40)是真的。