SPARC程序集,设置C标志
这个问题让我感到困惑,我真的不明白为什么我会遇到这个问题。我要用c创建一个程序,在设置c标志之前输出一个无符号值,使用assembly用addcc累加一个变量,并将该值发送回c中的main。我相信我的c代码是正确的:SPARC程序集,设置C标志,c,assembly,32-bit,sparc,C,Assembly,32 Bit,Sparc,这个问题让我感到困惑,我真的不明白为什么我会遇到这个问题。我要用c创建一个程序,在设置c标志之前输出一个无符号值,使用assembly用addcc累加一个变量,并将该值发送回c中的main。我相信我的c代码是正确的: unsigned int func(); int main(void){ printf("The max value before the C flag is set is: %u\n", func()); } 现在问题来了与大会 .global func func:
unsigned int func();
int main(void){
printf("The max value before the C flag is set is: %u\n", func());
}
现在问题来了与大会
.global func
func: save %sp, -128, %sp
addcc %g0, 1, %g0
clr %l0
loop:
bcs away
mov %l0, %i0
addcc %i0, 1, %l0
ba loop
nop
away:
ret
restore
这应该做的是在设置C标志时累加%l0,将值传递回%i0并返回它。当我运行这个时,我得到0。这对我来说没有意义,因为我相信我应该得到一个更大的数字。任何帮助都将不胜感激。问题是Sparc上的分支被延迟了——分支后的下一条指令将在分支实际执行之前执行。因此,当你有:
bcs away
mov %l0, %i0
设置C标志并执行此分支时,mov
仍将执行,用%l0
覆盖%i0
中的值(上次添加该集合C之前的值)(添加后的值--0)
如果你在这里贴一个nop:
bcs away
nop
mov %l0, %i0
它应该给您想要的值。问题是Sparc上的分支被延迟了——分支后的下一条指令将在分支实际执行之前执行。因此,当你有:
bcs away
mov %l0, %i0
设置C标志并执行此分支时,mov
仍将执行,用%l0
覆盖%i0
中的值(上次添加该集合C之前的值)(添加后的值--0)
如果你在这里贴一个nop:
bcs away
nop
mov %l0, %i0
它应该为您提供所需的值。C标志表示进位?然后我猜当值为
UINT\u MAX
时,它被设置为递增。现在,UINT_MAX+1
是0。这正是我假设的,唯一的问题是我不知道如何在重置之前返回数字。我可以使用:bcs(设置c标志时的分支)或bcc(清除c标志时的分支)在设置标志后将值减量1(或者这是作弊吗?)。subcc?我试过了,我得到-1。不,我不认为这会被认为是作弊。我曾经一度认为,由于某种原因,它没有循环,经过调试,是的,它正在循环,所以它必须重置。但减去一就等于-1!令人沮丧的!C标志表示进位?然后我猜当值为UINT\u MAX
时,它被设置为递增。现在,UINT_MAX+1
是0。这正是我假设的,唯一的问题是我不知道如何在重置之前返回数字。我可以使用:bcs(设置c标志时的分支)或bcc(清除c标志时的分支)在设置标志后将值减量1(或者这是作弊吗?)。subcc?我试过了,我得到-1。不,我不认为这会被认为是作弊。我曾经一度认为,由于某种原因,它没有循环,经过调试,是的,它正在循环,所以它必须重置。但减去一就等于-1!令人沮丧的!太棒了,太棒了!我从来没有想过,但这很有道理。请澄清一下,在c语言中,这是打印无符号数字的正确方法吗?我可以评论一下“四个字母的单词是什么?”@DillonBurton:是的,%u
打印一个无符号int
。@DanielFischer:是早期RISC设计的常见错误。@Chris Dodd:或者简单地使用bcs,一个远离的来取消延迟槽(如果分支被占用,则不执行它),非常棒!我从未想过这一点,但它非常有意义。只是一些澄清,在c中,这是打印未签名数字的正确方法吗?我可以评论一下“四个字母的单词是什么?”@DillonBurton:是的,%u
打印一个无符号int
@DanielFischer:是早期RISC设计的一个常见错误。@Chris Dodd:或者简单地使用bcs,a away
取消延迟槽(如果分支被占用,则不执行它),