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