【问题标题】:SPARC Assembly, setting the C flagSPARC 程序集,设置 C 标志
【发布时间】:2013-04-02 21:21:01
【问题描述】:

这让我感到困惑,我真的无法弄清楚为什么我会遇到这个问题。我将在 c 中创建一个程序,该程序在设置 C 标志之前输出一个无符号值,使用程序集通过 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

这应该做的是累积 %l0,当设置 C 标志时,将值传递回 %i0 并返回它。当我运行这个时,我得到 0。这对我来说很有意义,因为我相信我应该得到一个更大的数字。任何帮助将不胜感激。

【问题讨论】:

  • C 标志表示进位?然后我猜它在值为UINT_MAX 时设置为递增。现在,UINT_MAX + 1 为 0。
  • 这正是我的假设,唯一的问题是我不知道如何在重置之前返回数字。我可以使用:bcs(设置 c 标志时的分支)或 bcc(清除 c 标志时的分支)
  • 设置标志后将值减一(还是作弊?)。
  • subcc?我试过了,我得到-1。
  • 不,我认为这不会被视为作弊。我虽然有一段时间因为某种原因它没有循环,调试过,是的,它正在循环,所以它必须重置。减去一个会带我到-1!令人沮丧!

标签: c assembly 32-bit sparc


【解决方案1】:

问题是 Sparc 上的分支被延迟了——分支之后的下一条指令将在分支实际执行之前执行。所以当你有:

bcs away
mov %l0, %i0

当设置了 C 标志并采用此分支时,mov 仍将执​​行,用%l0(在添加 -- 0)。

如果你在这里坚持:

bcs away
nop
mov %l0, %i0

它应该给你你想要的价值。

【讨论】:

  • 太棒了!我从来没有想过这件事,但它是完全有道理的。只是在c中进行一些澄清,这是否是打印无符号数字的正确方法?
  • 我可以评论“四个字母的单词是什么?”
  • @DillonBurton:是的,%u 打印出unsigned int
  • @DanielFischer:Branch delay slots 是早期 RISC 设计的常见错误特征。
  • @Chris Dodd:或者干脆使用bcs,a awayannul延迟槽(如果分支被占用则不执行),stackoverflow.com/questions/604119/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多