Mips 试图理解SYSCALL 5示例时,文本%占位符的顺序令人困惑

Mips 试图理解SYSCALL 5示例时,文本%占位符的顺序令人困惑,mips,mips64,edumips64,Mips,Mips64,Edumips64,我正在学习MIPS64并使用EduMIPS64模拟器 我理解以下示例的说明,我尝试一个又一个周期地执行它,但我不知道编译器如何知道哪个数字或字符串与相应的占位符匹配,以及它们与format\u str的关系,因此在.code部分的末尾,将format\u str的地址放入r14 我知道系统调用期望其参数的地址存储在寄存器R14中,但其他所有参数与该地址的关系如何(format\u str) 对于每个%s,%d或%i占位符,SYSCALL 5需要一个 参数,从上一个参数的地址开始。当 SYSCAL

我正在学习MIPS64并使用EduMIPS64模拟器

我理解以下示例的说明,我尝试一个又一个周期地执行它,但我不知道编译器如何知道哪个数字或字符串与相应的占位符匹配,以及它们与
format\u str
的关系,因此在
.code
部分的末尾,将
format\u str
的地址放入
r14

我知道系统调用期望其参数的地址存储在寄存器R14中,但其他所有参数与该地址的关系如何(
format\u str

对于每个
%s
%d
%i
占位符,
SYSCALL 5
需要一个 参数,从上一个参数的地址开始。当 SYSCALL为整型参数找到一个占位符,它期望 如果找到一个 字符串参数的占位符,它期望 字符串的地址

我试图通过记忆表征来理解它,但没有成功

            .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

谢谢。

模拟器实际上不需要了解占位符的任何信息

它知道格式字符串和所有其他值在模拟内存中的位置(
fs\u addr
),因为您在
r14
中传递了该地址。因此,模拟器只需将该地址映射到主机内存中的相应地址,将该地址的前两个字转换为
const char*
va_list
,然后调用
vprintf

我不知道EduMIPS64是否真的是这样,但这似乎是一个更简单的解决方案


这显示了示例中的每个占位符对应的内容:

"%dth of %s:\n%s version %i.%i is being tested!"
 |       |    |           |  | 
 |       |    |           |  +-+
 |       |    |           +-+  |
 |       |    +----------+  |  |
 |       +-------------+ |  |  |
 +--------->.word   5  | |  |  | 
                       | |  |  |
s1_addr:    .space  4<-+ |  |  |
s2_addr:    .space  4<---+  |  |
            .word   0<------+  |
            .word   5<---------+
%dth of%s:\n%s版本%i.%i正在测试中
|       |    |           |  | 
|       |    |           |  +-+
|       |    |           +-+  |
|       |    +----------+  |  |
|       +-------------+ |  |  |
+--------->.单词5 | | | |
| |  |  |

s1_addr:.space 4模拟器实际上不需要了解占位符的任何信息

它知道格式字符串和所有其他值在模拟内存中的位置(
fs\u addr
),因为您在
r14
中传递了该地址。因此,模拟器只需将该地址映射到主机内存中的相应地址,将该地址的前两个字转换为
const char*
va_list
,然后调用
vprintf

我不知道EduMIPS64是否真的是这样,但这似乎是一个更简单的解决方案


这显示了示例中的每个占位符对应的内容:

"%dth of %s:\n%s version %i.%i is being tested!"
 |       |    |           |  | 
 |       |    |           |  +-+
 |       |    |           +-+  |
 |       |    +----------+  |  |
 |       +-------------+ |  |  |
 +--------->.word   5  | |  |  | 
                       | |  |  |
s1_addr:    .space  4<-+ |  |  |
s2_addr:    .space  4<---+  |  |
            .word   0<------+  |
            .word   5<---------+
%dth of%s:\n%s版本%i.%i正在测试中
|       |    |           |  | 
|       |    |           |  +-+
|       |    |           +-+  |
|       |    +----------+  |  |
|       +-------------+ |  |  |
+--------->.单词5 | | | |
| |  |  |

s1地址:。例如,空格4,如果将数据从
fs_addr:.space 4.word 5
s1_addr:.space 4 s2_addr:.space 4`更改为:
fs_addr:.space 4
s1_addr:.space 4.word 5 s2_addr:.space 4`我替换了.word 5`的顺序和
s1 addr:.space 4
因此打印是:
5:EduMIPS64版本0.5的第48位测试我不明白为什么一开始是
48
。嗯,这种改变毫无意义。现在,您正在传递一个字符串指针,其中需要一个整数参数,以及一个整数,其中需要一个字符串指针。至于打印的“48”,s1
地址的低位16位可能恰好是
0x0030
(即48)。但同样,这种改变毫无意义,所以你不应该对结果读得太多。例如,如果将数据从
fs_addr:.space 4.word 5
s1_addr:.space 4 s2_addr:.space 4`更改为:
fs_addr:.space 4
s1_addr:.space 4.word 5 s2_addr:.space 4`我替换了.word 5`的顺序和
s1 addr:.space 4
因此打印是:
5:EduMIPS64版本0.5的第48位测试我不明白为什么一开始是
48
。嗯,这种改变毫无意义。现在,您正在传递一个字符串指针,其中需要一个整数参数,以及一个整数,其中需要一个字符串指针。至于打印的“48”,s1
地址的低位16位可能恰好是
0x0030
(即48)。但同样,这种改变毫无意义,所以你不应该对结果读得太多。