assembly 在MIPS中将整数保存为字符串

bxfogqkk  于 5个月前  发布在  其他
关注(0)|答案(3)|浏览(83)

我只是想知道,在MIPS中是否有任何方法可以将数字的总和存储为字符串,然后逐字节读取它们,例如:
sum 657 -> sw到一个. asphalt指令-> later lb在第一个索引上得到6(asphalt代码中)与5相同等等。这可能吗?

6bc51xsx

6bc51xsx1#

我相信ShinTakezou的答案中有一个缺陷。该行neg $a0,$a0将正数转换为负数,这会导致代码的奇怪输出。如果我们删除这一行。代码对正整数工作正常

zfciruhq

zfciruhq2#

当然,“. asphalt”指令只是一个.byte指令,主要用于存储ASCII文本

.ascii "PP"

字符串
就像

.byte 80,80


您可以使用.space为ASCII字符串腾出空间,然后在从整数到ASCII的转换中使用缓冲区,如果你的意思是“sw into . asnix directive”in integer。下面的代码使用itoa将“二进制数”转换为ASCII字符串并打印出来(仅用于测试)与print_string。该函数使用缓冲区并返回指向可用于打印的第一个ASCII数字的指针。这可以用作sprintf的第一个帮助函数-类似于函数实现。

.data

buffer:
         .space 32

      .text
      # the main supposes env. like spim or MARS
main:
      li   $a0, 1234      # a number
      jal  itoa
      move $a0, $v0
      li   $v0, 4         # print_string    
      syscall
      li   $v0, 10
      syscall             # exit

itoa:
      la   $t0, buffer+30  # pointer to almost-end of buffer
      sb   $0, 1($t0)      # null-terminated str
      li   $t1, '0'  
      sb   $t1, ($t0)     # init. with ascii 0
      li   $t3, 10        # preload 10

      slt  $t2, $a0, $0   # keep the sign
      beq  $a0, $0, iend  # end if 0
      bgtz $a0, loop
      neg  $a0, $a0       # absolute value (unsigned)
loop:
      div  $a0, $t3       # a /= 10
      mflo $a0
      mfhi $t4            # get remainder
      add  $t4, $t4, $t1  # convert to ASCII digit
      sb   $t4, ($t0)     # store it
      subu  $t0, $t0, 1   # dec. buf ptr
      bne  $a0, $0, loop  # if not zero, loop
      addiu $t0, $t0, 1   # adjust buf ptr
iend:
      beq  $t2, $0, nolz  # was < 0?
      addiu $t0, $t0, -1
      li   $t1, '-'
      sb   $t1, ($t0)
nolz:
      move $v0, $t0      # return the addr.
      jr   $ra           # of the string


当你在main中有了$v0之后,lb R, ($v0)选择“1”,lb R, 1($v0)选择第二个数字(2),依此类推;记住字符串是以null结尾的,所以如果你选择0(数字),你必须停止

oknrviil

oknrviil3#

这里是另一个实现,分解为utoa(用于无符号整数)和itoa(用于使用utoa的有符号整数)。它们提供两个返回值,一个是要打印的字符串的地址,另一个是要打印的字符串中的字符数的计数-这个计数在使用文件I/O系统调用时很有帮助。字符串缓冲区(长度至少为12个字符)作为参数传入,因此可以是全局的,也可以是堆栈上的,如测试main所示。

.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

的数据

相关问题