Mips 用整数和字符生成字符串
Mips make string with integers and chars
我对 mips 非常陌生。我不知道从哪里开始:
假设我有
li $t1, -3
li $t2, -9
我要打印的字符串是
(-3,-9)
我将其存储在什么数据结构中? 。字节? .space?
这是我目前所拥有的,它打印出“(,)”;我在正确的轨道上吗?我从这里去哪里?
string: .space 10
.text
.globl main
main: la $t0, string
li $t1, -3
li $t2, -9
li $t3, '('
li $t4, ','
li $t5, ')'
li $t6, '-'
sb $t3, ($t0)
sb $t4, 1($t0)
sb $t5, 2($t0)
j exit
exit:
li $v0, 4 # print the string
la $a0, string
syscall
li $v0, 10 # terminate program
syscall
Assembly (MIPS/MARS) 使用 C-style nul-terminated 字符串 — nul 字符,'\0' ascii 值 0,位于末尾并被解释为结束字符串, 但它本身不是字符串的一部分。
因此,请记住以 null 终止您的字符串。还要记住为字符串分配比字符串所需的多 1 个字节的存储空间,以保存该 nul 字节。请注意,.space
指令将为您提供初始为零的存储空间,但如果您多次使用该存储空间,那么您可能需要动态 nul-terminate。如果你把 "(-82,-45)" 放在那里然后重新开始进行另一次转换,从一开始就放 "(-9,-3)" — 没有 nul-termination 它实际上会保持 "(-9 ,-3)5)", 带有先前的剩余字符。
如果您要将数字转换为字符,您将需要一个名为 itoa
(代表整数到 ascii)的算法或打印数字或将数字转换为字符串。这些非常简单明了,其中有很多,尽管它们都很相似。这个想法是使用数学运算 produce/extract 个单独的数字,然后一次只有一个数字,转换为它们的 ascii 等价物以打印或放入字符串。
大多数 itoa
算法将检查是否 < 0,如果是,则发出 -
符号,然后取负数并继续处理,就好像它是正数(一旦取反,它就是).
最简单的 itoa
方法是,例如,如果您知道最多需要 2 位数字,则通过将数字除以 10 来隔离高位数字。因此,对于 45,则为 45 /10=4,然后加上“0”又名 48,你将得到 52,这是字符“4”的 ascii 码。接下来将 45 和 mod 乘以 10,即 45%10=5,再加上 48 得到 53,即“5”的代码。您可以将其概括为一个循环。
一些算法逆向计算以产生数字,因为这很容易做到:首先 mod 除以 10,然后除以 10,并重复直到该值变为零 (0)。 456%10->6,然后是 456/10->45,接下来是 45%10->5,然后是 45/10->4,接下来是 4%10->4 和 4/10->0,所以你停下来。 6, 5, 4, 打印或复印时只需将其反转即可。
您不需要为此考虑汇编语言,因为任何语言都可以将字节操作成字符串。你想从算法上思考(而不是在汇编中)。上面的内容可以用 C 语言完成,如果你不知道,在汇编语言中进行算法思考是很困难的;在汇编之前了解您要编写的代码也很有用。编写 C 版本,然后将其转换为汇编是值得的。
.space
将保留在程序启动时初始化为零的全局存储。
你也可以分配堆栈space或从堆中分配,但两者都比全局分配更复杂。
你的开始没问题,只需要在其中加入一些itoa
算法。
因为翻译数字有时会导致不同的字符数(例如,3 是一个字符长,而 -3 和 45 是两个字符长)。您的 itoa
方法将使用一个变量来告诉下一个存储位置(哪个字节),而不是像您当前正在做的那样使用固定偏移量。选择使用变量时,可以使用指针或索引。在这里使用指针是很自然的,但需要明确的是,索引也可以工作,并且任何一个都可以在 C 中完成,也可以在汇编中完成。当您向字符串中添加字符时,指针或索引需要提前,因此您始终知道下一步要去哪里(以及在完成将字符放入字符串后将 nul 终止符放在哪里)。
由于您要将 2 个不同的数字转换为字符串,一个好的方法可能是使用一个函数来提供帮助;然而,函数在汇编中增加了很多复杂性;这种复杂性可能最好在其他基础知识之后学习。
我对 mips 非常陌生。我不知道从哪里开始:
假设我有
li $t1, -3
li $t2, -9
我要打印的字符串是
(-3,-9)
我将其存储在什么数据结构中? 。字节? .space?
这是我目前所拥有的,它打印出“(,)”;我在正确的轨道上吗?我从这里去哪里?
string: .space 10
.text
.globl main
main: la $t0, string
li $t1, -3
li $t2, -9
li $t3, '('
li $t4, ','
li $t5, ')'
li $t6, '-'
sb $t3, ($t0)
sb $t4, 1($t0)
sb $t5, 2($t0)
j exit
exit:
li $v0, 4 # print the string
la $a0, string
syscall
li $v0, 10 # terminate program
syscall
Assembly (MIPS/MARS) 使用 C-style nul-terminated 字符串 — nul 字符,'\0' ascii 值 0,位于末尾并被解释为结束字符串, 但它本身不是字符串的一部分。
因此,请记住以 null 终止您的字符串。还要记住为字符串分配比字符串所需的多 1 个字节的存储空间,以保存该 nul 字节。请注意,.space
指令将为您提供初始为零的存储空间,但如果您多次使用该存储空间,那么您可能需要动态 nul-terminate。如果你把 "(-82,-45)" 放在那里然后重新开始进行另一次转换,从一开始就放 "(-9,-3)" — 没有 nul-termination 它实际上会保持 "(-9 ,-3)5)", 带有先前的剩余字符。
如果您要将数字转换为字符,您将需要一个名为 itoa
(代表整数到 ascii)的算法或打印数字或将数字转换为字符串。这些非常简单明了,其中有很多,尽管它们都很相似。这个想法是使用数学运算 produce/extract 个单独的数字,然后一次只有一个数字,转换为它们的 ascii 等价物以打印或放入字符串。
大多数 itoa
算法将检查是否 < 0,如果是,则发出 -
符号,然后取负数并继续处理,就好像它是正数(一旦取反,它就是).
最简单的 itoa
方法是,例如,如果您知道最多需要 2 位数字,则通过将数字除以 10 来隔离高位数字。因此,对于 45,则为 45 /10=4,然后加上“0”又名 48,你将得到 52,这是字符“4”的 ascii 码。接下来将 45 和 mod 乘以 10,即 45%10=5,再加上 48 得到 53,即“5”的代码。您可以将其概括为一个循环。
一些算法逆向计算以产生数字,因为这很容易做到:首先 mod 除以 10,然后除以 10,并重复直到该值变为零 (0)。 456%10->6,然后是 456/10->45,接下来是 45%10->5,然后是 45/10->4,接下来是 4%10->4 和 4/10->0,所以你停下来。 6, 5, 4, 打印或复印时只需将其反转即可。
您不需要为此考虑汇编语言,因为任何语言都可以将字节操作成字符串。你想从算法上思考(而不是在汇编中)。上面的内容可以用 C 语言完成,如果你不知道,在汇编语言中进行算法思考是很困难的;在汇编之前了解您要编写的代码也很有用。编写 C 版本,然后将其转换为汇编是值得的。
.space
将保留在程序启动时初始化为零的全局存储。
你也可以分配堆栈space或从堆中分配,但两者都比全局分配更复杂。
你的开始没问题,只需要在其中加入一些itoa
算法。
因为翻译数字有时会导致不同的字符数(例如,3 是一个字符长,而 -3 和 45 是两个字符长)。您的 itoa
方法将使用一个变量来告诉下一个存储位置(哪个字节),而不是像您当前正在做的那样使用固定偏移量。选择使用变量时,可以使用指针或索引。在这里使用指针是很自然的,但需要明确的是,索引也可以工作,并且任何一个都可以在 C 中完成,也可以在汇编中完成。当您向字符串中添加字符时,指针或索引需要提前,因此您始终知道下一步要去哪里(以及在完成将字符放入字符串后将 nul 终止符放在哪里)。
由于您要将 2 个不同的数字转换为字符串,一个好的方法可能是使用一个函数来提供帮助;然而,函数在汇编中增加了很多复杂性;这种复杂性可能最好在其他基础知识之后学习。