使用GNU C内联汇编在{J}中绘制一个字符

时间:2016-01-12 16:22:26

标签: c gcc x86 dos djgpp

我正在学习使用C和内联汇编在DOS下进行一些低级VGA编程。现在我正在尝试创建一个在屏幕上打印出角色的功能。

这是我的代码:

//This is the characters BITMAPS
uint8_t characters[464] = {
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x50,
  0x50,0x00,0x00,0x00,0x00,0x00,0x50,0xf8,0x50,0x50,0xf8,0x50,0x00,0x20,0xf8,0xa0,
  0xf8,0x28,0xf8,0x00,0xc8,0xd0,0x20,0x20,0x58,0x98,0x00,0x40,0xa0,0x40,0xa8,0x90,
  0x68,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x40,0x40,0x40,0x20,0x00,
  0x20,0x10,0x10,0x10,0x10,0x20,0x00,0x50,0x20,0xf8,0x20,0x50,0x00,0x00,0x20,0x20,
  0xf8,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x60,0x20,0x40,0x00,0x00,0x00,0xf8,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x08,0x10,0x20,0x40,0x80,
  0x00,0x70,0x88,0x98,0xa8,0xc8,0x70,0x00,0x20,0x60,0x20,0x20,0x20,0x70,0x00,0x70,
  0x88,0x08,0x70,0x80,0xf8,0x00,0xf8,0x10,0x30,0x08,0x88,0x70,0x00,0x20,0x40,0x90,
  0x90,0xf8,0x10,0x00,0xf8,0x80,0xf0,0x08,0x88,0x70,0x00,0x70,0x80,0xf0,0x88,0x88,
  0x70,0x00,0xf8,0x08,0x10,0x20,0x20,0x20,0x00,0x70,0x88,0x70,0x88,0x88,0x70,0x00,
  0x70,0x88,0x88,0x78,0x08,0x70,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x30,0x30,
  0x00,0x30,0x10,0x20,0x00,0x00,0x10,0x20,0x40,0x20,0x10,0x00,0x00,0xf8,0x00,0xf8,
  0x00,0x00,0x00,0x00,0x20,0x10,0x08,0x10,0x20,0x00,0x70,0x88,0x10,0x20,0x00,0x20,
  0x00,0x70,0x90,0xa8,0xb8,0x80,0x70,0x00,0x70,0x88,0x88,0xf8,0x88,0x88,0x00,0xf0,
  0x88,0xf0,0x88,0x88,0xf0,0x00,0x70,0x88,0x80,0x80,0x88,0x70,0x00,0xe0,0x90,0x88,
  0x88,0x90,0xe0,0x00,0xf8,0x80,0xf0,0x80,0x80,0xf8,0x00,0xf8,0x80,0xf0,0x80,0x80,
  0x80,0x00,0x70,0x88,0x80,0x98,0x88,0x70,0x00,0x88,0x88,0xf8,0x88,0x88,0x88,0x00,
  0x70,0x20,0x20,0x20,0x20,0x70,0x00,0x10,0x10,0x10,0x10,0x90,0x60,0x00,0x90,0xa0,
  0xc0,0xa0,0x90,0x88,0x00,0x80,0x80,0x80,0x80,0x80,0xf8,0x00,0x88,0xd8,0xa8,0x88,
  0x88,0x88,0x00,0x88,0xc8,0xa8,0x98,0x88,0x88,0x00,0x70,0x88,0x88,0x88,0x88,0x70,
  0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x00,0x70,0x88,0x88,0xa8,0x98,0x70,0x00,0xf0,
  0x88,0x88,0xf0,0x90,0x88,0x00,0x70,0x80,0x70,0x08,0x88,0x70,0x00,0xf8,0x20,0x20,
  0x20,0x20,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x88,0x88,0x88,0x88,0x50,
  0x20,0x00,0x88,0x88,0x88,0xa8,0xa8,0x50,0x00,0x88,0x50,0x20,0x20,0x50,0x88,0x00,
  0x88,0x50,0x20,0x20,0x20,0x20,0x00,0xf8,0x10,0x20,0x40,0x80,0xf8,0x00,0x60,0x40,
  0x40,0x40,0x40,0x60,0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x30,0x10,0x10,0x10,
  0x10,0x30,0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,
  0x00,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8};
/**************************************************************************
 *  put_char                                                              *
 *     Print char                                                         *
 **************************************************************************/
void put_char(int x ,int y,int ascii_char ,byte color){

    __asm__(
        "push %si\n\t"
        "push %di\n\t"
        "push %cx\n\t"
        "mov color,%dl\n\t"   //test color
        "mov ascii_char,%al\n\t"  //test char
        "sub $32,%al\n\t"
        "mov $7,%ah\n\t"
        "mul %ah\n\t"
        "lea $characters,%si\n\t"
        "add %ax,%si\n\t"
        "mov $7,%cl\n\t"
        "0:\n\t"
        "segCS %lodsb\n\t"   
        "mov $6,%ch\n\t"
        "1:\n\t"    
        "shl $1,%al\n\t"
        "jnc 2f\n\t"
        "mov %dl,%ES:(%di)\n\t"
        "2:\n\t"
        "inc %di\n\t"
        "dec %ch\n\t"
        "jnz 1b\n\t"
        "add $320-6,%di\n\t"
        "dec %cl\n\t"
        "jnz  0b\n\t"
        "pop %cx\n\t"
        "pop %di\n\t"
        "pop %si\n\t"
        "retn"

    );


}

我从PASCAL编写的这一系列教程中引导自己:http://www.joco.homeserver.hu/vgalessons/lesson8.html

我根据gcc编译器改变了汇编语法,但我仍然遇到这个错误:

Operand mismatch type for 'lea'
No such instruction 'segcs lodsb'
No such instruction 'retn'

修改

我一直在努力改进我的代码,至少现在我在屏幕上看到了什么。这是我更新的代码:

/**************************************************************************
 *  put_char                                                              *
 *     Print char                                                         *
 **************************************************************************/
void put_char(int x,int y){
    int char_offset;
    int l,i,j,h,offset;
    j,h,l,i=0;
    offset = (y<<8) + (y<<6) + x;               
    __asm__(

        "movl _VGA, %%ebx;" // VGA memory pointer   
        "addl %%ebx,%%edi;"  //%di points to screen


        "mov _ascii_char,%%al;"
        "sub $32,%%al;"
        "mov $7,%%ah;"
        "mul %%ah;"

        "lea _characters,%%si;"
        "add %%ax,%%si;"   //SI point to bitmap

        "mov $7,%%cl;"

        "0:;"
            "lodsb %%cs:(%%si);"   //load next byte of bitmap 

            "mov $6,%%ch;"
        "1:;"   
            "shl $1,%%al;"
            "jnc 2f;"
            "movb %%dl,(%%edi);"  //plot the pixel
        "2:\n\t"
            "incl %%edi;"
            "dec %%ch;"
            "jnz 1b;"
            "addl $320-6,%%edi;"
            "dec %%cl;"
            "jnz  0b;"


        :  "=D" (offset)
        : "d" (current_color)

    );


}

如果您看到上面的图像,我试图写下字母“S”。结果是您在屏幕左上角看到的绿色像素。无论x和y我给出了功能,它总是在同一点上绘制像素。

enter image description here

有人可以帮我纠正我的代码吗?

0 个答案:

没有答案