C 中的内联汇编,带有跳转和两个 return 语句
Inline assembly in C with a jump and two return statements
我想要一个 void
函数来打印进位(溢出)是否发生并打印(可能溢出)被加数的值。
这是我的尝试,但它确实想要编译:
#include <stdio.h>
typedef unsigned long ulong;
void
func()
{
ulong a = 3;
ulong b = 1;
ulong c;
__asm__(
"\taddq\t%2, %q0\n" /* Add b to a and store in c */
"\tjc\tcarry"
: "=r" (c) /* Outputs */
: "0" (a), "rme" (b) /* Inputs */
);
printf("no carry\nc = %lu\n", c);
return;
__asm__("carry:");
printf("carry\nc = %lu\n", c);
return;
}
int
main()
{
func();
}
但是,当我删除第一个 return
语句时它会运行,但如果没有发生进位,它会打印两次。
如何使用两个 return 语句来执行此操作?
您需要为此使用 asm goto
。为此,在 __asm__
之后添加 goto
,将标签更改为 C 标签,在 clobbers 之后传递标签,然后使用 %l
来引用它。这是应用了这些修复程序的程序:
#include <stdio.h>
typedef unsigned long ulong;
void
func()
{
ulong a = 3;
ulong b = 1;
ulong c;
__asm__ goto(
"\taddq\t%2, %q0\n" /* Add b to a and store in c */
"\tjc\t%l[carry]"
: "=r" (c) /* Outputs */
: "0" (a), "rme" (b) /* Inputs */
:
: carry
);
printf("no carry\nc = %lu\n", c);
return;
carry:
printf("carry\nc = %lu\n", c);
return;
}
int
main()
{
func();
}
尽管如评论中所述,但对于此用例,您应该只使用 __builtin_uaddl_overflow
代替,除非您的目标只是学习如何跳出内联汇编。
我想要一个 void
函数来打印进位(溢出)是否发生并打印(可能溢出)被加数的值。
这是我的尝试,但它确实想要编译:
#include <stdio.h>
typedef unsigned long ulong;
void
func()
{
ulong a = 3;
ulong b = 1;
ulong c;
__asm__(
"\taddq\t%2, %q0\n" /* Add b to a and store in c */
"\tjc\tcarry"
: "=r" (c) /* Outputs */
: "0" (a), "rme" (b) /* Inputs */
);
printf("no carry\nc = %lu\n", c);
return;
__asm__("carry:");
printf("carry\nc = %lu\n", c);
return;
}
int
main()
{
func();
}
但是,当我删除第一个 return
语句时它会运行,但如果没有发生进位,它会打印两次。
如何使用两个 return 语句来执行此操作?
您需要为此使用 asm goto
。为此,在 __asm__
之后添加 goto
,将标签更改为 C 标签,在 clobbers 之后传递标签,然后使用 %l
来引用它。这是应用了这些修复程序的程序:
#include <stdio.h>
typedef unsigned long ulong;
void
func()
{
ulong a = 3;
ulong b = 1;
ulong c;
__asm__ goto(
"\taddq\t%2, %q0\n" /* Add b to a and store in c */
"\tjc\t%l[carry]"
: "=r" (c) /* Outputs */
: "0" (a), "rme" (b) /* Inputs */
:
: carry
);
printf("no carry\nc = %lu\n", c);
return;
carry:
printf("carry\nc = %lu\n", c);
return;
}
int
main()
{
func();
}
尽管如评论中所述,但对于此用例,您应该只使用 __builtin_uaddl_overflow
代替,除非您的目标只是学习如何跳出内联汇编。