有没有人要对我说或评论?
#include <stdio.h>
int main() {
short unsigned result, low ,high;
low = 0;
high = 1;
__asm__ (
"movl $10, %%ecx \n\t"
"loop: mov %2, %%ax \n\t"
// "add %1, %%ax \n\t" // uncomment and result = 10
"mov %%ax, %0 \n\t"
"subl $1, %%ecx \n\t"
"jnz loop"
: "=r" (result)
: "r" (low) , "r" (high)
: "%ecx" ,"%eax" );
printf("%d\n", result);
return 0;
}
跟随生成的程序集
movl $1, %esi
xorl %edx, %edx
/APP
movl $10 ,%ecx
loop: mov %si, %ax
mov %dx, %bx
add %bx, %ax
mov %ax, %dx
subl $1, %ecx
jnz loop
/NO_APP
多亏了弄臣的解决之道:
: "=&r" (result) // early clober modifier
GCC内联汇编是高级编程,有很多陷阱。确保您确实需要它,并且不能用独立的程序集模块或使用本征代码的C代码替换它。或矢量支持。
如果您坚持内联汇编,那么您应该准备至少看看生成的汇编代码,并从那里试图弄清楚任何错误。显然,编译器不会省略您写入asm块的任何内容,它只是替换参数。如果您查看生成的代码,可能会看到如下内容:
add %dx, %ax
mov %ax, %dx
显然,编译器为参数0
和1
选择了dx
。允许这样做,因为默认情况下,它假定输入参数在写入任何输出之前已被使用。要发出不是这种情况的信号,您必须对输出操作数使用一个早期的clobber修饰符,因此它看起来像“=&r”
。
谢谢你的帮助。
我正在尝试同时处理MSVC和GCC编译器,同时更新这个代码库以在GCC上工作。但我不确定GCCs内联ASM是如何工作的。现在我并不擅长将ASM转换为C,否则我就会使用C而不是ASM。 我假设ROR13的工作方式类似于,但代码不会产生相同的输出。 什么是将这个内联ASM翻译成GCC的正确方法,或者这个代码的C翻译是什么?
在尝试让一些旧代码重新工作时(https://github.com/chaos4ever/chaos/blob/master/libraries/system/system_calls.h#l387,FWIW),我发现的一些语义似乎在最近的10-15年中发生了非常微妙但仍然危险的变化...:p 该代码在的旧版本(如2.95)中可以很好地工作。总之,这里是代码: 上面代码的问题是(在我的例子中为4.
我的理解是,当编写gcc样式的内联asm时,您必须非常具体和准确地了解所有的输入和输出参数(和clobbers),这样编译器就会确切地知道如何为代码分配寄存器,以及它可以对那些寄存器的值和asm代码可能读取和/或修改的任何内存假设什么。编译器使用这些信息尽可能地优化周围的代码(如果它认为内联asm对任何东西都没有影响,甚至完全删除它)。对此不够具体可能会导致不正确的行为,因为编译器是根据您的不正确
问题内容: 我有一个这样的测试程序: 它产生以下输出: 我期望(1)和(3)相同,以及(2)和(4)相同。 使用gcc版本:gcc.real(Ubuntu 4.4.1-4ubuntu9)4.4.1 怎么了? 问题答案: 根据C标准 §6.5.7.3 ,按类型大小移动是未定义的行为: 6.5.7按位移位运算符 (…)如果右操作数的值为负或大于 或等于 提升后的左操作数的宽度,则行为未定义。 您的编译
尝试使用gcc:https://github.com/wolf9466/cpuminer-multi/blob/master/cryptonight_aesni.c编译此源文件时遇到此错误 “CRYPTONIGT_AESNI.c:162:4:错误:操作数约束不一致”