我想像这样转换一个while循环:
i=0;
while ( (s[i]!='t') && (i<=20) ) {
d[i]=c[i];
i++;
}
汇编代码有2个条件。 我怎样才能做到这一点? 下面是while中有1个条件的版本。
#################################################
# lab3_3a.s #
# while loop char!=ASCII 0 #
#################################################
.text
.globl __start
__start: # execution starts here
li $t1,0 # counter for string
li $s0,'t' # chararacter to end copy
while: lbu $t0,string($t1) # load a character
sb $t0,copy($t1) # copy character
beq $t0,$s0,end # if character to end copy then exit loop
addi $t1,$t1,1 # increment counter
b while # repeat while loop
end: li $t2,0
sb $t2,copy($t1) # append end character to copied string
la $a0,copy # display copy
li $v0,4
syscall
li $v0,10 # exit
syscall
.data
string: .asciiz "Mary had a little lamb"
copy: .space 80
谢谢你们。
答案 0 :(得分:1)
所以,你已经成功地将其中一个条件反转并用它跳出循环。您是否可以为另一方做同样的事情?
li $t1,0 # counter for string
li $s0,'t' # chararacter to end copy
li $s1,20 # count to end copy
while: lbu $t0,string($t1) # load a character
sb $t0,copy($t1) # copy character
beq $t0,$s0,end # if character to end copy then exit loop
bgt $t1,$s1,end # if count exceeds limit then exit loop
addi $t1,$t1,1 # increment counter
b while # repeat while loop
答案 1 :(得分:1)
i=0;
while ( (s[i]!='t') && (i<=20) ) {
d[i]=c[i];
i++;
}
如果将s
定义为char s[20];
,则会包含两个错误,首先(i<=20)
将是一个太多。在数组长度测试中使用<=
是非常不寻常的,如果定义了char s[21];
它可能仍然是正确的,但是在源代码中有两个不同的“幻数”,20和21。第二个错误是的,即使你有正确的长度测试,(s[i]!='t')
也会在i
验证之前执行,因此在最后一个字符处你将获得越界访问。
无论如何,C用C语言写成更像“汇编”的方式:
i=0;
while(true) { // Your "b while" is doing this already
if (20 < i) break; // test length first, to avoid s[21] (out of bounds)
if ('t' == s[i]) break; // test for "terminator" character
//^^ Yoda notation, to catch typo like (s[i]='t') as error
d[i]=c[i];
++i; // pre-increment form is more accurate to your intent
// As you don't need original value after incrementation
}
// breaks will jump here.
这应该很容易在汇编中重写,试试吧......
编辑:并且您的原始程序集不是“while”,而是“do-while”,即第一个字节的副本将在所有情况下执行,这不是C示例正在执行的操作。
edit2:同时当然这假设你知道布尔逻辑代数,正如每个程序员所必须的那样。即你知道的:
!(A && B) <=> (!A) || (!B)