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

发布于 2024-09-03 06:25:49 字数 150 浏览 3 评论 0原文

我只是想知道,MIPS 中是否有任何方法可以将数字总和存储为字符串,然后逐字节读取它们,例如:

总和 657 -> sw 进入 .ascii 指令 ->稍后对第一个索引进行 lb 操作,得到 6(以 ascii 代码表示),与 5 相同,依此类推。这可能吗?

I was just wondering, is there any way in MIPS to store a summation of numbers as a string and later read them byte by byte, for example:

the sum 657 -> sw into a .ascii directive -> later lb on the first index to get 6 (in ascii code) same with 5 and so on. Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

橪书 2024-09-10 06:25:49

我认为 ShinTakezou 的回答有缺陷。
行负 $a0, $a0
会将正数转换为负数,这会导致代码输出奇怪的结果。
如果我们删除这一行。这些代码对于正整数工作正常

I believe there is a flaw in ShinTakezou's answer.
The line neg $a0, $a0
will convert the positive number to negative, which results in a weird output for the code.
If we remove this line. The codes work fine for positive integer

桜花祭 2024-09-10 06:25:49

当然。 “.ascii”指令不是一个,而是一个专注于 ASCII 文本存储的 .byte 指令,

   .ascii "PP"

就像

   .byte 80,80

您可以使用 .space 为 ASCII 字符串腾出空间,然后在转换中使用缓冲区从整数到 ASCII,如果您的意思是整数的“sw into .ascii 指令”。以下代码使用 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

在主文件中有 $v0 后,lb R, ($v0) 选择“1”,lb R, 1($v0) 选择第二个数字 (2) 并很快;请记住该字符串以 null 结尾,因此如果您选择 0(数字),则必须停止

Of course. The ".ascii" directive is none but a .byte directive focused on the storage of ASCII text

   .ascii "PP"

is like

   .byte 80,80

You can use .space to make room for your ASCII string, and then use the buffer in the convertion from integer to ASCII, if you mean this by "sw into .ascii directive" of in integer. The following code converts the "binary number" into a ASCII string using itoa and prints it (just for testing) with print_string. The function uses a buffer and returns the pointer to the first ASCII digit usable for printing. This could be used as a first helper function for a sprintf-like function implementation.


       .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

After you have $v0 in the main, lb R, ($v0) picks "1", lb R, 1($v0) picks second digit (2) and so on; remember the string is null-terminated, so if you pick 0 (numeric), you have to stop

云仙小弟 2024-09-10 06:25:49

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

    .text
    j main      # jump around functions, start at main for testing itoa

# 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

Here's another implementation, factored into utoa for unsigned integers, and itoa for signed integers that uses utoa.  These provide two return values, one is the address of the string to print, and the other is a count of the number of characters in the string to print — this count is helpful when using file I/O syscalls.  The string buffer (of at least 12 characters in length) is passed in as parameter, so can be a global, or on the stack as the test main illustrates.

    .text
    j main      # jump around functions, start at main for testing itoa

# 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文