2013-03-20 140 views
0

我試圖找到一個非常基本的C++內聯彙編x86-64的例子,與此類似:簡單X86-64 C++內聯彙編的 「Hello World」 的例子

a Simple "Hello World" Inline Assembly language Program in C/C++

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!

+5

什麼操作系統?通常情況下,您不要在x86-64代碼中使用「int 0x21」(DOS中斷)。 – nrz 2013-03-20 21:19:26

+0

Google'intel編譯器內聯彙編' – 2013-03-20 21:20:59

+1

如果您在Windows上,請嘗試[DosBox(x86模擬器)](http://www.dosbox.com/)以使用0x21中斷。 – deepmax 2013-03-20 21:23:39

回答

5

您發佈的代碼是16位代碼。 64位Windows(或任何版本的Linux)不支持16位代碼。 [這是有點bug,因爲它將長度設置爲6,當字符串的實際長度爲12時...]

您可能會弄清楚如何在Windows代碼中執行相同的操作,但是我失敗了以瞭解如何從彙編程序在Windows中進行系統調用。編寫一些代碼,用於實際應用,比如計算字符串中的字符數。

當然,您將需要使用Intel或GCC編譯器,因爲Microsoft編譯器不允許64位模式的內聯彙編程序。

下面是使用「read timestamp counter」指令的一個內聯彙編程序示例,該指令將與gcc編譯器一起工作(兼容性也應與Intel編譯器一起工作)。

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); 
} 
+0

我只是想要一個例子,一個x86-64程序集的小例子,它是在一個普通的C++主函數中內聯的 – mezamorphic 2013-03-20 21:44:24

+0

使用哪種編譯器? – 2013-03-20 21:45:28

+0

關於彙編,有英特爾語法和AT&T語法。由Mats提供的答案是AT&T語法,如下所示:__asm__ __volatile __(「mov%0,%0」:「+ r」(dummy));整個聲明可以放在內聯中。 – 2013-03-20 21:59:06

1

AT & T與Intel彙編格式。

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。這很大程度上與調試有關。