是否可以使用可用于非顺序选项的Jumpterable使用MIPS进行开关/情况?
我想在MIPS中使用开关/盒子和夹具练习。目前,我能够通过彼此堆叠几个BEQ命令来实现类似的逻辑。我更喜欢将其切换到使用Case的单个开关语句。不幸的是,案例不是按顺序排列的。有一个用户菜单在其中输入字符(ASCII值),并基于该字符,发生了一个操作。例如,他们可以选择“ a”,'d','n','x'。显然,这不是在井井有条...我正在考虑将选项存储一个数组,并将其视为枚举(据我所知,在MIP中不存在),这将解决非序列问题并更容易将案例转换为适当的字符。
到目前为止,这是我的代码,以帮助清理问题: 请注意,问题是在开关/跳转中而不是在情况下执行的实际逻辑/操作
示例:
//switch case sample based on char
char ch;
cout << "Enter a character: ";
cin >> ch;
switch (ch)
{
case 'N':
//action to perform
cout << "N: " << endl;
break;
case 'A':
//action
cout << "A: " << endl;
break;
default:
cout << "You entered an invalid character" << endl;
break;
}
和我当前的MIPS解决方案:
.data
.asciiz
enterMenu: "Enter a menu option (N,A,M,D,X):\n"
.word
JT: N,A,M,D,X #all the possible cases we want to deal with
.text
la $a0, enterMenu #load meu prompt
li $v0, 4 #print prompt
syscall
li $v0, 12 #read char from user
syscall
add $t0, $v0, $0 #move the character to a temporary register (holds switch value)
#switch (k) k = $s5
slti $t3, $t0, 65 # Test if k < 65 (A's ascii value)
bne $t3, $zero, Exit # if k < A, go to Exit
slti $t3, $t0, 90 #Test if k > 90 (Z's ascii value)
beq $t3, $zero, Exit # if k > Z, go to Exit
beq $t0, 65, A # if k = A, go to A
beq $t0, 68 , D # if k = D, go to D
beq $t0, 77, M # if k = M, go to M
beq $t0, 78, N # if k = N, go to n
beq $t0, 88, X # if k = X, go to X
编辑:菜单可能如下:
Cases: .byte 'N','A','M','D','X' #added this in after
或类似:
JumpTable .word POW, DIV, MULT, PLUS, MINUS, PRINT, EXIT #different cases
Operations: .byte '^', '/', '*', '+', '-', '@', 'x'
EndOps: #hold end spot
这样我应该是理论上我应该是能够加载第一个字节并比较它...然后移至下一个字节等。 然后,问题将成为如何使它们对应的(从用户输入)到可夹具的偏移,然后再进行选择案例。
I want to practice using switch/cases and JumpTables in MIPS. Currently, I am able to achieve a similar logic via stacking several BEQ commands after each other. I'd prefer to switch it over to using a single switch statement with cases. Unfortunately, the cases are not in sequential order. There is a user-menu where they enter a character (ascii value) and based on that character, an action occurs. For example, they can choose 'A', 'D', 'N', 'X'. Obviously, that is not in order... I am considering to store an array with the options and treat it as an ENUM (which doesn't exist in MIPS as far as I'm aware) which would solve the non-sequential issue and have an easier time converting the case to the proper character.
This is a bit of my code as of now to help clear things up:
Note that the issue is with the switch/jump rather than the actual logic/action performed in the cases
C++ Example:
//switch case sample based on char
char ch;
cout << "Enter a character: ";
cin >> ch;
switch (ch)
{
case 'N':
//action to perform
cout << "N: " << endl;
break;
case 'A':
//action
cout << "A: " << endl;
break;
default:
cout << "You entered an invalid character" << endl;
break;
}
and my current mips solution:
.data
.asciiz
enterMenu: "Enter a menu option (N,A,M,D,X):\n"
.word
JT: N,A,M,D,X #all the possible cases we want to deal with
.text
la $a0, enterMenu #load meu prompt
li $v0, 4 #print prompt
syscall
li $v0, 12 #read char from user
syscall
add $t0, $v0, $0 #move the character to a temporary register (holds switch value)
#switch (k) k = $s5
slti $t3, $t0, 65 # Test if k < 65 (A's ascii value)
bne $t3, $zero, Exit # if k < A, go to Exit
slti $t3, $t0, 90 #Test if k > 90 (Z's ascii value)
beq $t3, $zero, Exit # if k > Z, go to Exit
beq $t0, 65, A # if k = A, go to A
beq $t0, 68 , D # if k = D, go to D
beq $t0, 77, M # if k = M, go to M
beq $t0, 78, N # if k = N, go to n
beq $t0, 88, X # if k = X, go to X
Edit: The menu an probably be stored as follows:
Cases: .byte 'N','A','M','D','X' #added this in after
or as such:
JumpTable .word POW, DIV, MULT, PLUS, MINUS, PRINT, EXIT #different cases
Operations: .byte '^', '/', '*', '+', '-', '@', 'x'
EndOps: #hold end spot
Then theoretically I should be able to load in the first byte and compare it ... then move on to the next one etc.
The question would then become on how to have them correspond (from the user input) to the JumpTable offset and then to picking cases.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
beq
s系列与相当分散的少数情况一样好(例如a
-x )。
代码指针的数据表必须有24个条目,许多条目将访问默认情况(无匹配)。
使用表的代码顺序将:
addiu
)sltiu
) /bnez 用于未签名的比较)
>
%hi(table)hi(table)/
%%的汇编器lo(表)
让您留下lw
即时的表地址的一部分,总计9指令(或8)和可能的数据缓存遗漏,尽管订购机可以并行化2个范围检查指令的执行。 (或者如果适当安排它们,则是按级超量表。)
beq
的系列是10个指令(beq
带常数的 是伪指令扩展到立即加载,然后比较分支),尽管并非所有人都会执行,并且可以订购绩效。 (最常见。)因此,如果有20个以上的情况,我可能会切换到表版本,因为在20个情况下,平均有10个说明将执行(假设分布相等,更好,如果您可以订购已知的说明分发。)
如果“默认”情况最常见,则范围检查和/或比特图检查,例如
0x12345&amp; (1&lt;&lt; c)
可以简单地排除是特殊情况之一,而无需全部浏览。The series of
beq
s is as good as you're going to get for a small number of cases that are fairly spread out (e.g.A
-X
).A data table of pointers to code would have to have 24 entries, many going to the default (no match) case.
Code sequence to use the table would:
addiu
)sltiu
/bnez
for unsigned compare)%hi(table)
/%lo(table)
to let you leave part of the table address for thelw
immediate),For a total of 9 instructions (or 8) and a possible data cache miss, though an out of order machine would be able to parallelize execution of the 2 range-check instructions. (Or an in-order superscalar if you schedule them appropriately.)
The series of
beq
's for your set is 10 instructions (beq
with a constant is a pseudo instruction that expands to first load the immediate, then compare & branch), though not all will always execute, and they can be ordered for performance. (Most common first.)So, I would probably switch to the table version if there were more than 20 or so cases, since at 20 cases, on average, 10 instructions would execute (assuming equal distribution, better if you can order for known distribution.)
If the "default" case is most common, a range-check and/or a bitmap check like
0x12345 & (1<<c)
could rule out being one of the special cases quickly, without going through them all.谢谢Erik的回答,我能够自己弄清楚这一点:
我只在这里放置最相关的信息,您需要将两个阵列加载到寄存器中,然后继续进行此操作。请注意,ASCIIZ自动以 /0结束(null终结器),以了解字符串已完成(因此,用户输入的情况不在表中)...然后发送错误消息。
这些将在.data中
,这将在.text中
Thank you Erik for your answer, I was able to figure it out a bit differently on my own:
I am only putting here the most relevant bits of information, you will need to load both arrays into a register and then proceed before doing this. Note that asciiz automatically ends with /0 (null terminator) to know that the string is finished being read (and therefore the user entered case is not in the table)... then send an error message.
These will be in .data
and this will be in .text