我有一些写和读VGA的I/O端口的代码。我正在尝试在内联汇编程序中实现工作的C代码功能。我正在使用Open Watcom 2.0,并针对DOS 16位进行编译。
为了写入VGA上的调色板,我想出了这个。这不能正常工作。
编辑: setPaletteColor的代码并不完全准确。我已经更新了以反映实际的代码。
void setPaletteColor (unsigned char index, rgbColor *p_color)
{
_asm
{
; tell VGA card we are going to update a palette register
mov dx,PALETTE_MASK
mov al,0xff
out dx,al
; tell VGA which register we will be updating
mov dx,PALETTE_REGISTER_WR
mov al,index
out dx,al
; update the color in the register at index
mov dx,PALETTE_DATA
mov al,*p_color
out dx,al
mov al,*p_color // this is actually *(p_color+1) but this actually gets the next structure not the next data member, so I left it out of the code I typed for my question.
out dx,al
mov al,*p_color // same here, actually is *(p_color+2)
out dx,al
}
}为了阅读,我带了这个。这也不能正常工作。
void getPaletteColor (unsigned char index, rgbColor *p_color)
{
unsigned char *p_red = &p_color->red;
unsigned char *p_green = &p_color->green;
unsigned char *p_blue = &p_color->blue;
_asm
{
; tell VGA card we are going to read a palette register
mov dx,PALETTE_MASK
mov al,0xff
out dx,al
; tell VGA which register we will be reading
mov dx,PALETTE_REGISTER_RD
mov al,index
out dx,al
; read the data into the color struct at 'p_color'
mov dx,PALETTE_DATA
in al,dx
mov *p_red,al
in al,dx
mov *p_green,al
in al,dx
mov *p_blue,al
}
}现在,这里是可以工作的纯C版本。
void setPaletteColor (unsigned char index, rgbColor *p_color)
{
outp(PALETTE_MASK,0xff);
outp(PALETTE_REGISTER_WR, index);
outp(PALETTE_DATA,p_color->red);
outp(PALETTE_DATA,p_color->green);
outp(PALETTE_DATA,p_color->blue);
}和用于阅读的。
void getPaletteColor (unsigned char index, rgbColor *p_color)
{
outp(PALETTE_MASK,0xff);
outp(PALETTE_REGISTER_RD, index);
p_color->red = inp(PALETTE_DATA);
p_color->green = inp(PALETTE_DATA);
p_color->blue = inp(PALETTE_DATA);
}注意:我不能使用'.‘运算符或内联程序集中的'->‘运算符,因为编译器不支持它。
下面是rgbColor结构的定义。
typedef struct rgbColorTag
{
unsigned char red;
unsigned char green;
unsigned char blue;
} rgbColor;发布于 2016-10-31 12:10:42
一个很好的问题可以描述它是如何不工作的。只是说“不工作”让我认为这是一个语法错误,因为我不知道Watcom风格的内联asm。我只是假设它类似于MSVC风格,并且在asm中使用C取消引用操作符是一个语法错误(例如在mov al,*p_color中)。
显然,这是Open Watcom的有效语法,但是你加载的是相同字节的3倍。也许可以尝试使用mov al, *(p_color+1)作为第二个字节?尽管这可能只是执行C指针数学运算,并获得下一个结构的开始。请查看您的编译器手册,了解可用的语法选项。
您也可以将指针加载到寄存器中,并自己使用它的偏移量(使用像mov al, [si+1]这样的寻址模式)。这取决于3个结构成员的布局顺序,没有填充,但我认为这应该是一个安全的假设。你可以随时检查编译器的asm输出,看看它是如何布局结构的。
由于您的结构的布局顺序是正确的,因此您应该能够使用OUTS遍历其中的3个字节。或者甚至REP OUTS,这样你就不需要编写循环了。
cld
mov si, p_color ; get the function arg in a register
mov dx, PALETTE_DATA
mov cx, 3
rep outsb ; OUT 3 times, to port DX, using data from DS:[SI] (and do SI++ post-increment)同样的,对于阅读,
cld
mov di, p_color
mov dx, PALETTE_DATA
mov cx, 3
rep insb ; IN 3 times, to port DX, using data from DS:[DI] (and do DI++)https://stackoverflow.com/questions/40336338
复制相似问题