[英]Using calloc in Turbo C++ In-Line Assembly
我曾经在 8086 汇编和 Turbo C++ 中编写代码,我决定使用内联汇编进行一些测试,但我遇到了这个问题:
此代码完美运行:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
FILE *fp;
int regvga=0x13;
int regtxt=0x03;
int vgamem=0xA000;
unsigned char data[64000];
void main (void)
{
fp=fopen("pic1.dat","rb");
fread(data,64000,1,fp);
fclose(fp);
asm{
mov ax,regvga
int 0x10
mov ax,vgamem
mov es,ax
cld
mov cx,32000
lea si,data
mov di,0
rep movsw
}
getch();
asm{
mov ax,regtxt
int 0x10
}
}
但是这段代码根本不起作用。
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
FILE *fp;
int regvga=0x13;
int regtxt=0x03;
int vgamem=0xA000;
unsigned char *data;
void main (void)
{
data=(char*)calloc(64000,sizeof(char));
fp=fopen("pic1.dat","rb");
fread(data,64000,1,fp);
fclose(fp);
asm{
mov ax,regvga
int 0x10
mov ax,vgamem
mov es,ax
cld
mov cx,32000
lea si,data
mov di,0
rep movsw
}
getch();
asm{
mov ax,regtxt
int 0x10
}
free(data);
}
它编译没有错误,但图像显示不正确。 怎么了?
堆位于不同的段中(显然,给定数组的大小)。 正如@fuz 所提议的,使用lds
。 此外,使用push ds
和pop ds
允许程序随后继续使用原始数据段。
push ds
lds si,data
mov di,0
rep movsw
pop ds
根据 memory model,您可能还需要将data
声明为“远”指针,并使用远堆函数:
unsigned char far *data;
data = (char far *)farcalloc(64000,sizeof(char));
farfree(data);
免责声明:我不能 100% 确定使用 Borland 的内联汇编将远指针加载到ds:si
中的正确方法。 您可能需要使用调试器来解决这个问题。
@fuz @klutz @Ruud Helderman
大家好:感谢您的大力帮助,很抱歉回复晚了:)
其实解决方法很简单:只需要将lea si,data
替换为lds si,[data]
,当然还要保留DS
寄存器。 代码将是这样的:
asm{
mov ax,regvga
int 0x10
push ds
mov ax,vgamem
mov es,ax
cld
mov cx,32000
lds si,[data]
mov di,0
rep movsw
pop ds
}
无需使用 faralloc,因为仅当我们的数组大于 64K 时才需要使用 faralloc。 当然,还需要使用大型 Model 进行编译。
好吧,我正在使用 Turbo C++ 3.0,因为我已经为 Windows、Amiga、Atari 和 Spectrum 制作了一个小射手,现在我想将其转换为 MS-DOS。 由于我有点懒,我不想从根目录开始在汇编中对其进行编码,而是使用 Atari 版本的 C 代码并使用内联汇编来处理图形内容:)。 更多关于我的小游戏的信息: http://sardonic.planetaclix.pt/
干杯,MadAxe
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.