如何在 EDUMIPS64 模拟器中打印数组或格式化字符串?
How to print an array, or a formatted string in EDUMIPS64 simulator?
该程序的文档非常有限。为了做到这一点,我几乎没有什么可以借鉴的。除了程序的 PDF 之外,只有这个:
.data
format_str: .asciiz "%dth of %s:\n%s version %i.%i is being tested!"
s1: .asciiz "June"
s2: .asciiz "EduMIPS64"
fs_addr: .space 4
.word 5
s1_addr: .space 4
s2_addr: .space 4
.word 0
.word 5
test:
.code
daddi r5, r0, format_str
sw r5, fs_addr(r0)
daddi r2, r0, s1
daddi r3, r0, s2
sd r2, s1_addr(r0)
sd r3, s2_addr(r0)
daddi r14, r0, fs_addr
syscall 5
syscall 0
你可以去看看here。 EDU/WINMIPS64 与常规 MIPS 汇编有很大不同
有几个段落对此进行了解释,但帮助不大。无论如何,这里打印了一个格式化的字符串,以及一些字符串参数(存储在 s1 和 s2 中)和整数参数(它们存储在哪里?)。
我有两个数组存储在内存中。我已经亲自对它们执行了指示,现在我想打印它们。我如何在这样的格式化字符串上提供这两个整数(它们是双字,即需要存储 8 个字节)?帮助 material 没有解释。
这是到目前为止我设法创建的代码(大量评论):
....
dadd $s4, $zero, $zero ; i = 0
printOutput: ; print results from the 2 arrays
beq $s4, 960, end ; if (i = size = 960 / 8) goto end
dadd $s1, $s4, $s2 ; full address of 1st array
dadd $s0, $s4, $s3 ; full address of 2nd array
daddi $a3, $zero, printString ; address ofstring to be printed stored in $a3
ld $v0, 0($s1) ; $v0 will be used to print 1st array[i]. Is this right?
ld $v1, 0($s2) ; $v1 will be used to print 2nd array[i]. Is this right? Which register to use for supplying a formatted string to print integers? It is not explained anywhere!
dadd , $zero, $a3 ; print string. is the register to syscall instructions. But i'm just guessing with this. I really don't know how it should handle. I just supplied $a3 because it seems more intuitive.
syscall 5 ; prints ouput (on the MEM stage)
daddi $s4, $s4, 8 ; i++
j printOutput
end:
如果有人知道如何做到这一点,如果 he/she 可以分享,我将不胜感激。任何地方都没有这方面的例子。谢谢。
更新
在迈克尔的帮助下,通过反复试验,我找到了问题的主要原因。我们为输出字符串和其他内存地址提供标签的顺序非常敏感。通过反复试验,我发现我们必须遵守以下命令:
.data
format_string .asciiz "%d and %i etc.."
start_address .space 4
syscallArg1 .space 4 ; 1st parameter to syscall 5
syscallArg2 .space 4 ; 2nd parameter to syscall 5
---other labels go here---
.text
---code---
请注意,我们必须向 </code> 提供 start_address 标签,该标签不得包含任何内容(只是一些可用的空 space)。在这之前,格式化字符串必须在这之后,<code>syscall 5
的参数必须在这之后。其他标签可以在所有这些标签之后或之前。
手册上说的是格式字符串的地址,后面跟着零个或多个参数(例如整数或字符串地址),在连续内存中,然后加载该内存的起始地址在执行 sycall 5
.
之前进入 r14
他们的示例代码对我来说看起来有点不正确,因为他们应该使用 sw
而不是 sd
在内存中存储 r2
和 r3
(假设字符串地址实际上适合 32 位)。
所以你需要在数据部分保留一些space,然后先存储你的格式字符串的地址,然后是任何参数。然后把那块内存的起始地址放在r14
中。例如,如果您的格式字符串是 "%d, %d"
并且您要打印的两个值在 r2
和 r3
中,您将 sw
r2
和 r3
直接在存储格式字符串地址的位置之后。
例如:
.data
format_str: .asciiz "%d"
printf_args: .space 8
...
.code
daddi r5, r0, format_str
sw r5, printf_args(r0)
daddi r5, r0, 123
sw r5, printf_args+4(r0)
daddi r14, r0, printf_args
syscall 5
该程序的文档非常有限。为了做到这一点,我几乎没有什么可以借鉴的。除了程序的 PDF 之外,只有这个:
.data
format_str: .asciiz "%dth of %s:\n%s version %i.%i is being tested!"
s1: .asciiz "June"
s2: .asciiz "EduMIPS64"
fs_addr: .space 4
.word 5
s1_addr: .space 4
s2_addr: .space 4
.word 0
.word 5
test:
.code
daddi r5, r0, format_str
sw r5, fs_addr(r0)
daddi r2, r0, s1
daddi r3, r0, s2
sd r2, s1_addr(r0)
sd r3, s2_addr(r0)
daddi r14, r0, fs_addr
syscall 5
syscall 0
你可以去看看here。 EDU/WINMIPS64 与常规 MIPS 汇编有很大不同
有几个段落对此进行了解释,但帮助不大。无论如何,这里打印了一个格式化的字符串,以及一些字符串参数(存储在 s1 和 s2 中)和整数参数(它们存储在哪里?)。
我有两个数组存储在内存中。我已经亲自对它们执行了指示,现在我想打印它们。我如何在这样的格式化字符串上提供这两个整数(它们是双字,即需要存储 8 个字节)?帮助 material 没有解释。
这是到目前为止我设法创建的代码(大量评论):
....
dadd $s4, $zero, $zero ; i = 0
printOutput: ; print results from the 2 arrays
beq $s4, 960, end ; if (i = size = 960 / 8) goto end
dadd $s1, $s4, $s2 ; full address of 1st array
dadd $s0, $s4, $s3 ; full address of 2nd array
daddi $a3, $zero, printString ; address ofstring to be printed stored in $a3
ld $v0, 0($s1) ; $v0 will be used to print 1st array[i]. Is this right?
ld $v1, 0($s2) ; $v1 will be used to print 2nd array[i]. Is this right? Which register to use for supplying a formatted string to print integers? It is not explained anywhere!
dadd , $zero, $a3 ; print string. is the register to syscall instructions. But i'm just guessing with this. I really don't know how it should handle. I just supplied $a3 because it seems more intuitive.
syscall 5 ; prints ouput (on the MEM stage)
daddi $s4, $s4, 8 ; i++
j printOutput
end:
如果有人知道如何做到这一点,如果 he/she 可以分享,我将不胜感激。任何地方都没有这方面的例子。谢谢。
更新
在迈克尔的帮助下,通过反复试验,我找到了问题的主要原因。我们为输出字符串和其他内存地址提供标签的顺序非常敏感。通过反复试验,我发现我们必须遵守以下命令:
.data
format_string .asciiz "%d and %i etc.."
start_address .space 4
syscallArg1 .space 4 ; 1st parameter to syscall 5
syscallArg2 .space 4 ; 2nd parameter to syscall 5
---other labels go here---
.text
---code---
请注意,我们必须向 </code> 提供 start_address 标签,该标签不得包含任何内容(只是一些可用的空 space)。在这之前,格式化字符串必须在这之后,<code>syscall 5
的参数必须在这之后。其他标签可以在所有这些标签之后或之前。
手册上说的是格式字符串的地址,后面跟着零个或多个参数(例如整数或字符串地址),在连续内存中,然后加载该内存的起始地址在执行 sycall 5
.
r14
他们的示例代码对我来说看起来有点不正确,因为他们应该使用 sw
而不是 sd
在内存中存储 r2
和 r3
(假设字符串地址实际上适合 32 位)。
所以你需要在数据部分保留一些space,然后先存储你的格式字符串的地址,然后是任何参数。然后把那块内存的起始地址放在r14
中。例如,如果您的格式字符串是 "%d, %d"
并且您要打印的两个值在 r2
和 r3
中,您将 sw
r2
和 r3
直接在存储格式字符串地址的位置之后。
例如:
.data
format_str: .asciiz "%d"
printf_args: .space 8
...
.code
daddi r5, r0, format_str
sw r5, printf_args(r0)
daddi r5, r0, 123
sw r5, printf_args+4(r0)
daddi r14, r0, printf_args
syscall 5