0

我试图找到一个非常基本的 C++ 内联 x86-64 汇编示例,类似于:

C/C++ 中的简单“Hello World”内联汇编语言程序

char msg[] = "Hello, world";

asm {
    mov ax,4       // (I/O Func.)
    mov bx,1       // (Output func)  
    lds cx, msg   // (address of the string)
    mov dx,6       //  (lenght of the string)
    int 0x21       // system call
}

这将与英特尔编译器一起使用。有人可以帮忙吗?

编辑关于操作系统我在 Windows 和 Linux 上有 ICC - 让我们说 Linux!

4

2 回答 2

5

您发布的代码是 16 位代码。64 位 Windows(或任何版本的 Linux)不支持 16 位代码。[而且有点问题,因为它将长度设置为 6,而字符串的实际长度是 12...]

您可能会弄清楚如何在 Windows 代码中做同样的事情,但我看不到学习如何从汇编程序中进行系统调用的意义。编写一些代码来做一些你可以在现实生活中实际应用的事情,例如计算字符串中的字符数。

当然,您将需要使用 Intel 或 GCC 编译器,因为 Microsoft 编译器不允许在 64 位模式下使用内联汇编程序。

这是使用“读取时间戳计数器”指令的内联汇编程序的一个小示例,它将与 gcc 编译器一起使用(并且通过兼容性也应该与英特尔编译器一起使用)。

static __inline__ unsigned long long rdtsc(void)
{
    unsigned hi, lo;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
于 2013-03-20T21:36:20.653 回答
1

AT&T 与英特尔汇编格式。

at&t noprefix                   intel
mov eax, -4(ebp,edx,4)          mov DWORD PTR[-4 +ebp +edx *4], eax
mov eax, -4(ebp)                mov DWORD PTR[-4 +ebp], eax
mov edx, (ecx)                  mov DWORD PTR[ecx], edx
lea (   ,eax,4), eax            lea eax, DWORD PTR[8 + eax*4]
lea (eax,eax,2), eax            lea eax, DWORD PTR[eax*2+eax]

或这个。

asm(".intel_syntax noprefix");
asm("mov eax, ebx");

asm(".att_syntax prefix");
asm("mov %ebx, %eax");

AT&T 语法。

int main(int argc, char *argv[])
{
int x=1, f=2, fa=3;
asm("int $0x3");
asm("mov 4%0,%%eax"::"m"(x));
asm("movss 4%0,%%xmm1"::"m"(f));
asm("fld 4%0"::"m"(fa));
return 0;
}

请注意,其中一个区别是“%”的使用和分配给寄存器的方向。

更多讨论herehere。其中大部分与调试有关。

于 2013-03-21T05:23:41.727 回答