cout 未能提供输出可能是由于内联汇编
Posted
技术标签:
【中文标题】cout 未能提供输出可能是由于内联汇编【英文标题】:cout fails to give output probably due to inline assembly 【发布时间】:2020-02-03 21:45:53 【问题描述】:我正在使用 Visual Studio 2019 开发人员命令提示符。内联汇编代码是简单的除法和余数。使用命令cl /EHsc filename.cpp
编译没有错误。屏幕上绝对没有显示任何内容。它最多需要 4 秒的运行时间。
#include<iostream>
using namespace std;
int main()
int x=10,y=20;
int z=0,r=0;
//z=x/y
//r=x%y
__asm
MOV EAX,x
IDIV y
MOV z,EAX
MOV r,EDX
cout<<"z = "<<z<<"\tr = "<<r<<endl;
return 0;
【问题讨论】:
我在这段代码中看不到任何会干扰cout
的内容。您只需要使用调试器跟踪代码即可。但是你为什么要使用内联汇编,而不是简单地在普通 C++ 代码中使用 /
和 %
运算符?让编译器根据需要为您优化。
如果您想提高效率,请使用std::div
1.使用调试器。 2. 忘记内联汇编 3. 忘记汇编
@MichaelChourdakis "忘记组装" 如果您想成为一名工程师,开发驱动程序或接近嵌入式硬件上的骨协议,该怎么办。或者,如果您想在操作系统内核上进行开发。或者如果你想编写编译器?或者如果你想在 HPC 上工作?或者只是为了更好地理解幕后发生的事情以编写更好的抽象?或者如果你想写一门新的编程语言怎么办?
@G.Sliepen:这是 MSVC,而不是 GNU C 内联汇编。 MSVC 解析你的 asm 并找出你触摸了哪些寄存器。
【参考方案1】:
您在MOV EAX,x
和IDIV y
指令之间缺少CDQ
。没有它,EDX
寄存器中有一个未知值,可能导致除法溢出。 CDQ
指令会将EAX
签名扩展为EDX
。
MOV EAX,x
CDQ
IDIV y
【讨论】:
@MohammadShahwez:还值得一提的是,这个内联汇编完全没有意义;编译器将为您执行此优化(使用一个idiv
的两个输出),或者甚至不使用idiv
作为编译时间常数除数更好。 (即使使用运行时变量除数。)使用 MSVC 内联 asm 引入了两个输出的存储/重新加载。见What is the difference between 'asm', '__asm' and '__asm__'?
@MohammadShahwez:另外值得一提的是:在更好的操作系统下,您会看到程序因除法异常而崩溃。例如在 Linux 等类 Unix 操作系统上,操作系统会以 SIGFPE 算术异常终止您的进程,并且命令行 shell 会报告这一事实。在 Windows 下,也许尝试 Powershell,以防它只是 cmd
不好并且没有报告异常程序终止。以上是关于cout 未能提供输出可能是由于内联汇编的主要内容,如果未能解决你的问题,请参考以下文章