【问题标题】:memcpy doesn't do anythingmemcpy 什么都不做
【发布时间】:2020-09-18 06:46:13
【问题描述】:

我试图在我的 VGA dos 程序中加入双缓冲,但是当我使用 memcpy 函数时似乎出现了问题。

我确定我分配了所需的内存,但它似乎不起作用。

这是程序:

#include <dos.h>
#include <string.h>
unsigned char* doublebuffer;
unsigned char far* VGA = (unsigned char far*) 0xA0000000L;
void setmode(int mode)
{
   union REGS regs;
   regs.h.ah = 0x0;
   regs.h.al = mode;
   int86(0x10, &regs, &regs);
}

void main()
{
    doublebuffer =(unsigned char *) malloc(320*200);

    setmode(0x13);
    VGA[9*320+11] = 0x41;
    doublebuffer[9*320+10] = 15;
    if(doublebuffer[9*320+10]  != 15)
    {
     exit(1);
    }
    memcpy(VGA, doublebuffer, 320*200);
    getch();
}

malloc 有效,因为程序不会崩溃,缓冲区接受颜色,但 memcpy 似乎不起作用,因为屏幕上没有任何内容。

当我直接写入 VGA 地址时,它可以工作。 (11, 9) 上会有一个粉红色像素,但 (10, 9) 上没有白色像素

【问题讨论】:

  • 你确定如果你写一些东西到VGA地址它对屏幕有影响吗?例如。 VGA[320*10] = 128;
  • @Login 对不起,我注意到了,但是是的,VGA 地址适用于所有 320*200 像素
  • 我会尝试的事情(这里只是头脑风暴):使用calloc() 将双缓冲区初始化为零并测试NULL 的结果,使用memmove() 只是为了好玩,将全局变量移入main() ...退出大声fprintf(stderr, "\aBUFFER MISMATCH!!!\a\n"); exit(1);
  • edit 并显示有效的代码(直接写入VGA 内存的代码)。
  • _fmemcpy(......

标签: c dos vga


【解决方案1】:

您的问题是您可能正在使用近数据模型进行编译,例如默认情况下数据指针附近的微型或小型内存模型。 Near 数据指针只能引用默认数据段中的东西,而 VGA 帧缓冲区位于该默认段之外。虽然您正确地将变量 VGA 定义为远指针,但当您将此指针传递给 memcpy 时,它会转换为近指针,因为 memcpyvoid * 作为第一个参数。由于您使用的是近端数据模型,void * 是近端指针类型。

要解决这个问题,您应该使用函数_fmemcpy 而不是将void far * 指针作为参数,因此您的VGA 指针不会被转换为近端指针。

您还应该注意编译器警告。您的编译器应该通过如下消息警告您此问题:

Warning: test.c 24: Suspicious pointer conversion in function main

您还应该注意并修复有关在没有原型的情况下调用函数的警告,因为正确原型化的函数允许编译器警告上述可疑指针转换。

【讨论】:

    猜你喜欢
    • 2019-03-08
    • 2016-12-24
    • 2017-04-18
    • 2011-08-03
    • 2014-05-11
    • 2014-09-10
    • 1970-01-01
    • 2023-03-29
    • 2013-09-28
    相关资源
    最近更新 更多