我正在尝试在C ++(Dev-CPP)中使用Assembly,它不会按原样输出字符串。经过一些研究后,我发现它使用了AT& T语法。我的代码不会输出它只是出现汇编消息的字符串。 这是我的代码:
#include <iostream>
using namespace std;
int main()
{
asm(".section .data");
asm("hello: .string\"Hello, World!$\"\n");
asm(".section .text");
asm("movl $0x09, %ah \n");
asm("mov hello, %dx\n");
asm("int 0x21");
system("PAUSE");
return 0;
}
我可以得到一些帮助。
答案 0 :(得分:2)
理论上,只有使用DJGPP(用于DOS的gcc端口)编译的程序才能通过DOS扩展器IFF合法地使用DOS服务功能,您可以在DOS或Windows(XP及以下版本,通常不是Vista / 7/8)中运行它们。此外,gcc不会生成16位x86代码,这正是您所期待的。
此外,你应该真的,真正学习一些内联汇编(google it up)。
如果您的代码看起来像可编译的版本:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
asm(".section .data");
asm("hello: .string\"Hello, World!$\"\n");
asm(".section .text");
asm("movb $0x09, %ah\n"); // movl->movb
asm("movl $hello, %edx\n"); // mov->movl,hello->$hello,dx->edx
asm("int $0x21"); // 0x21->$0x21
system("PAUSE");
return 0;
}
但它仍然不太可能是良好的内联汇编,因为:
这样的事情会更好:
asm volatile (
".section .data\n"
"hello: .string \"Hello, World!$\"\n"
".section .text\n"
"movb $0x09, %ah\n"
"movl $hello, %edx\n"
"int $0x21\n"
);
不幸的是,即使使用DJGPP,这仍然无效。这个问题与DJGPP和DPMI主机(CWSDPMI)完成的内存分段设置有关,可能是虚拟内存。我不知道那里究竟出了什么问题,但上面的代码并没有按原样运作。
所以,请弄清楚你正在为你的程序编译什么操作系统,并为该操作系统适当地编写内联汇编代码,即使用正确的寄存器和系统调用机制。
DOS int 21h函数在本机Windows和Linux应用程序中不起作用。期。你的教程错了。
答案 1 :(得分:0)
要扩展Alexey的答案(如何克服分段问题),这将编译(并可能在DOS上运行):
asm volatile(
"call 0f\n"
".byte 'H','e','l','l','o','W','o','r','l','d','!',0\n"
"0: pop %0\n"
"push %ds\n"
"push %cs\n"
"pop %ds\n"
"int $0x21\n"
"pop %ds\n" : "d"(0), "a"(9) : : "memory", "cc");
这个想法是在代码中内联字符串,但跳过它;该调用的返回地址是字符串的起始地址。然后暂时使数据段与代码段相同,调用DOS INT并在此之后恢复正确的数据段。