简体   繁体   English

在 Turbo C++ 在线组装中使用 calloc

[英]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 dspop 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM