[英]Using calloc in Turbo C++ In-Line Assembly
I use to code in 8086 assembly and in Turbo C++ and I decided to make some tests with in-line assembly but I got stuck with this problem:我曾经在 8086 汇编和 Turbo C++ 中编写代码,我决定使用内联汇编进行一些测试,但我遇到了这个问题:
This code works perfectly:此代码完美运行:
#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
}
}
But this code simply doesn't work.但是这段代码根本不起作用。
#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);
}
It compiles without errors but the image is displayed incorrectly.它编译没有错误,但图像显示不正确。 What's wrong?
怎么了?
The heap is in a different segment (evidently, given the size of the array).堆位于不同的段中(显然,给定数组的大小)。 As proposed by @fuz, use
lds
.正如@fuz 所提议的,使用
lds
。 Additionally, use push ds
and pop ds
to allow the program to continue afterwards with the original data segment.此外,使用
push ds
和pop ds
允许程序随后继续使用原始数据段。
push ds
lds si,data
mov di,0
rep movsw
pop ds
Depending on the memory model, you may also need to declare data
as a 'far' pointer, and use far heap functions:根据 memory model,您可能还需要将
data
声明为“远”指针,并使用远堆函数:
unsigned char far *data;
data = (char far *)farcalloc(64000,sizeof(char));
farfree(data);
Disclaimer: I'm not 100% sure about the proper way to load a far pointer into ds:si
with Borland's inline assembly.免责声明:我不能 100% 确定使用 Borland 的内联汇编将远指针加载到
ds:si
中的正确方法。 You may need to use the debugger to work that out.您可能需要使用调试器来解决这个问题。
@fuz @klutz @Ruud Helderman @fuz @klutz @Ruud Helderman
Hi guys: Thanks for your great help and sorry for this late reply :)大家好:感谢您的大力帮助,很抱歉回复晚了:)
In fact, the solution is very simple: it's just need to replace lea si,data
for lds si,[data]
and of course preserve the DS
register.其实解决方法很简单:只需要将
lea si,data
替换为lds si,[data]
,当然还要保留DS
寄存器。 The code will be something like this:代码将是这样的:
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
}
There is no need to use faralloc because faralloc is only needed when our array is bigger than 64K.无需使用 faralloc,因为仅当我们的数组大于 64K 时才需要使用 faralloc。 And of course there is need to compile using the Large Model.
当然,还需要使用大型 Model 进行编译。
Well, I'm using Turbo C++ 3.0 because I have made a little shooter for Windows, Amiga, Atari and Spectrum and now I want to convert it to MS-DOS.好吧,我正在使用 Turbo C++ 3.0,因为我已经为 Windows、Amiga、Atari 和 Spectrum 制作了一个小射手,现在我想将其转换为 MS-DOS。 As I'm a little lazy I don't want to code it in assembly from the root but use the C code from Atari version and use in-line assembly to handle the graphical stuff:).
由于我有点懒,我不想从根目录开始在汇编中对其进行编码,而是使用 Atari 版本的 C 代码并使用内联汇编来处理图形内容:)。 More info about my little game here: http://sardonic.planetaclix.pt/
更多关于我的小游戏的信息: http://sardonic.planetaclix.pt/
Cheers, MadAxe干杯,MadAxe
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.