2016-01-13 48 views
-1

我有一個簡單的功能使用DJGPP和256的VGA DOS框繪製在C聯彙編像素:情節像素VGA與內聯彙編

byte *VGA = (byte *)0xA0000; 
void plot_pixel(int x, int y, byte color){ 

    int offset; 
    if(x>32 && x <=320 && y>0 && y<180){ 
    //x=x-1; 
    //y=y-1; 
    if(x<0){x=0;} 
    if(y<0){y=0;} 
    offset = (y<<8) + (y<<6) + x; 
    VGA[offset]=color; 

    } 


} 

I'm上翻譯它內聯彙編工作,我有這個:

void plot_pixel(int x, int y, byte color){ 

    int offset; 
    if(x>32 && x <=320 && y>0 && y<180){ 
    //x=x-1; 
    //y=y-1; 
    if(x<0){x=0;} 
    if(y<0){y=0;} 
    // offset = (y<<8) + (y<<6) + x; 
    // VGA[offset]=color; 

    __asm__ (
      "mov $0xA000,%edx;" 
      "mov $320,%ax;" 
      "mul y;" //not sure how to reference my variable here 
      "add x,%ax;" //not sure how to reference my variable here 
      "mov %ax,%bx;" 
      "mov color,%al;" //not sure how to reference my variable here 
      "mov %al,%bx:(%edx);" 


     ); 
    } 


} 

但是我在編譯器上得到幾個錯誤。我不熟悉GCC內聯程序集,因此在糾正我的代碼方面的任何幫助都將得到澄清。

+0

可能的重複[打印字符與C(gcc編譯器)中的內聯彙編](http://stackoverflow.com/questions/34748733/printing-character-with-inline-assembly-in-c-gcc-compiler ) – Olaf

回答

2

首先,對於細分,您必須使用段寄存器(並且無法將0xA000加載到通用寄存器中並使用它)。然而...

DJGPP有它自己的「DOS擴展器」,並在32位保護模式下運行你的代碼;並且保護模式下的細分工作方式非常不同出於這個原因,你不能像使用真實模式一樣使用細分;並且必須創建一個「段描述符」,您可以使用特殊的庫函數。有關這方面的示例,請參見http://www.delorie.com/djgpp/v2faq/faq18_4.html

對於GCC的內聯彙編,編譯器完全不瞭解彙編,大多隻是將代碼直接插入到編譯器的輸出中(可能在執行一些簡單的文本替換之後)。因此,你需要告訴編譯器哪些寄存器用於輸入,哪些寄存器用於輸出,哪些東西(寄存器,內存等)被「破壞」(由你的代碼修改)。

您應該能夠在線查找多個描述如何提供輸入/輸出/ clobber列表及其格式的頁面。

注意:DJGPP是「GCC移植到DOS」,因此GCC的大部分信息對DJGPP的工作原理是相同的;並且您將有更多的運氣搜索(例如)「GCC內嵌程序集」,因爲您將搜索「DJGPP內聯程序集」,因爲GCC仍在使用中。