.text
j main # jump around functions, start at main for testing itoa
x
# function utoa ( unsigned int, char* ) returns struct { char *, int }
# a0, unsigned number to convert to sring
# a1, pointer to free space large enough to hold integer as string (at least 11 bytes)
# v0, pointer to the beginning of the converted string
# v1, count of number of characters in the string
utoa:
addiu $a1, $a1, 11 # move to the end of the buffer
sb $0, ($a1) # null terminator (sometimes helpful not always necessary)
li $t0, 10
li $v1, 0
utoaLoop:
div $a0, $t0 # divide by 10
mfhi $t2 # remainder is digit to print
addiu $a1, $a1, -1 # back up one byte's worth
addi $t2, $t2, '0' # convert numeric digit to ascii digit
sb $t2, ($a1) # store in buffer
addi $v1, $v1, 1 # increment counter of how many characters
mflo $a0 # capture quotient
bnez $a0, utoaLoop # quotient not zero, so repeat to get another digit
move $v0, $a1 # return pointer to start of character string
# note: $v1 holds count of number of characters in string
# the string is null terminated (but the null is not counted)
jr $ra
# function itoa ( int, char* ) returns struct { char *, int }
# a0, signed number to convert to sring
# a1, pointer to free space large enough to hold integer as string (at least 12 bytes)
# v0, pointer to the beginning of the converted string
# v1, count of number of charactes in the string
# itoa calls utoa (using tco if the number is positive),
# and otherwise prepends a '-' to the string.
itoa:
bltz $a0, ineg
j utoa # tail call optimization
ineg:
addiu $sp, $sp, -4 # space for our return address
sw $ra, ($sp)
neg $a0, $a0 # negate number and convert as unsigned
jal utoa
addiu $v0, $v0, -1 # prepend a '-' character
li $t0, '-'
sb $t0, ($v0)
addi $v1, $v1, 1 # and increment character count
lw $ra, ($sp)
addiu $sp, $sp, 4
jr $ra
# a simple main for testing itoa
main:
addiu $sp, $sp, -64 # create some stack space
li $a0, 1234 # number to print
move $a1, $sp
jal itoa
move $a0, $v0 # return 1: where to print
move $s0, $v1 # return 2: how many chars to print
li $v0, 4
syscall
li $a0, '\n'
li $v0, 11
syscall
move $a0, $s0
li $v0, 1
syscall
li $a0, '\n'
li $v0, 11
syscall
li $a0, -1234
move $a1, $sp
jal itoa
move $a0, $v0 # return 1: address of string to print
move $s0, $v1 # return 2: how many chars to print
li $v0, 4
syscall
li $a0, '\n'
li $v0, 11
syscall
move $a0, $s0
li $v0, 1
syscall
li $a0, '\n'
li $v0, 11
syscall
li $v0, 10
syscall
3条答案
按热度按时间6bc51xsx1#
我相信ShinTakezou的答案中有一个缺陷。该行neg $a0,$a0将正数转换为负数,这会导致代码的奇怪输出。如果我们删除这一行。代码对正整数工作正常
zfciruhq2#
当然,“. asphalt”指令只是一个.byte指令,主要用于存储ASCII文本
字符串
就像
型
您可以使用
.space
为ASCII字符串腾出空间,然后在从整数到ASCII的转换中使用缓冲区,如果你的意思是“sw into . asnix directive”in integer。下面的代码使用itoa将“二进制数”转换为ASCII字符串并打印出来(仅用于测试)与print_string。该函数使用缓冲区并返回指向可用于打印的第一个ASCII数字的指针。这可以用作sprintf的第一个帮助函数-类似于函数实现。型
当你在main中有了$v0之后,
lb R, ($v0)
选择“1”,lb R, 1($v0)
选择第二个数字(2),依此类推;记住字符串是以null结尾的,所以如果你选择0(数字),你必须停止oknrviil3#
这里是另一个实现,分解为
utoa
(用于无符号整数)和itoa
(用于使用utoa
的有符号整数)。它们提供两个返回值,一个是要打印的字符串的地址,另一个是要打印的字符串中的字符数的计数-这个计数在使用文件I/O系统调用时很有帮助。字符串缓冲区(长度至少为12个字符)作为参数传入,因此可以是全局的,也可以是堆栈上的,如测试main
所示。x
的数据