SPARC程序集,设置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:

这个问题让我感到困惑,我真的不明白为什么我会遇到这个问题。我要用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: 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
取消延迟槽(如果分支被占用,则不执行它),