2016-09-14 9 views
1

MS-DOS 6.22で動作し、MSCDEXと割り込みを使用してCD-ROMにアクセスする必要があるTurbo C++ 3.0でCプログラムを作成しようとしています。トラックを再生する。ドキュメントファイルからTurbo C++ 3.0のインラインアセンブリコード(TASM)を作成する

Turbo Cは私にとっては問題ではありませんでした。私はすでにそれを行いましたが、うまくいきましたが、今はthisのドキュメントを使ってCD-ROMデバイスドライバの名前を取得しようとしています。ここで

は私のコードです:

#include <stdio.h> 
#include <dos.h> 

void main(){ 
    clrscr(); 
    CDname(); 

    printf("\nPress a button to exit the program."); 
    getch(); 
} 

void CDname(){ 
    char myArray[15]; 
    int i; 

    asm{ 
     mov AX,1501H 
     les BX,DWORD PTR[myArray] 
     int 2FH 
    } 

    for(i=0; i < 15; i++){ 
     printf("\nArray = %c", myArray[i]); 
    } 
} 

そして、ここでは、私は従うことをしようとしているドキュメントの小さな一部です:

How do I get the name of the CD-ROM device driver? 

     First, you need to know how many CD-ROMs you have (see question 
     2.01, How many CD-ROMs are present?). You need a block of memory 
     whose size, in bytes, is 5 times the number of CD-ROMs present. 
     This code will fill that array: 

     mov AX,1501H 
     les BX,DriverArray 
     int 2FH 

     Each 5-byte element in the array consists of the drive's subunit 
     number (a CD-ROM device driver may support several drives as 
     subunits), followed by the address of the drive's device driver. 
     The filename is 10 bytes into the device driver. The filename is 
     at most 8 bytes long, and if less than 8 bytes, is terminated by 
     a space (20H). 

問題は、私は置く必要があるということですCD- ROMの名前をmyArrayの中に入れますが、このようにして私は自分が何をしているのかよく分かりません。誰かが私を助けることができますか?

ありがとうございます!

+0

名前が配列にありません。名前はデバイスドライバ内にあり、配列はその配列を指します。 –

+0

@RossRidgeあなたは私にそれを説明するための例を挙げることができますか?アセンブラ文と混同しているので、私は本当に感謝しています –

+0

'char myArray [15]'の代わりに、 'struct foo1 {char subunit;構造体foo2 * ptr; }; '' struct foo2 {char junk [10]; char name [8];}; 'あなたの構造体はpack(1)を使用しなければならないことに注意してください。また、 '名前'はほとんど確実にヌルで終了しないことに注意してください。最後に、foo1のインスタンスを宣言するときに、3つのデバイスが必要な場合は、 'struct foo1 devicedata [3];'という適切なサイズにしてください。 –

答えて

2

memset()を使用してmyarrayを最初にゼロにすると、インラインアセンブリがその場所に情報を書き込んでいないことがわかります。これは、LES命令がfarポインタをES:BX からまで、ES:BXのアドレスをあなたが望むメモリに設定するのではなく、初期化されていないメモリにロードしているためです。

これらのサンプル命令では、DriverArrayにfarポインタがあると想定していました。割り込み機能が実際に期待しているのは、ES:BXがあなたの配列を指すことです。 ESは既にデータセグメント(DSとSSのように)を指しているので、単に は "lea bx、[myarray]"を使用してスタック上の配列のオフセットでBXをロードします。

(少なくとも私の仮想マシン上で)「INT 2Fhを」実行は、それがmyarrayのバッファに次のバイトを書き込みます

00 00 00 EF 04 

は私が最初のバイトは、サブユニットでなければならないと仮定し、残りの4つのバイトfarポインタ04EF:0000に対応する。あなたは、ドライバのファイル名がで命令が言ったと同じように、10をオフセットMSCD000で見ることができます

04EF:0000 00 00 A8 03 00 C8 DC 00 E7 00 4D 53 43 44 30 30 ..........MSCD00 
04EF:0010 30 20 00 00 04 01 00 4F 41 $B 20 41 54 41 50 49 0 .....OAK ATAPI 
04EF:0020 20 49 44 45 20 43 44 2D 52 4F 4D 98 00 3F 15 3B IDE CD-ROM..... 

:ターボデバッガでは、私のマシン上でこの場所は、次のバイトを持っていました。

したがって、CD-ROM情報のfarポインタを参照解除し、10個のオフセットを追加できる構造を作成するだけで済みます。そして、あなたはこれまで、文字列の書式指定子を使用して、printf関数を使用して文字列を指定することができます。

struct CDINFO 
{ 
    unsigned char subunit; 
    unsigned char far* pData; 
}; 

...ここ

printf("CDROM filename = \"%Fs\"\n", 
    ((CDINFO*)myarray)->pData + 10 
); 

が完了改訂コードです:

注:私は気にしませんでした終端スペースなしでCD-ROMのファイル名を表示します。それを削除したり、他のCD-ROMドライバ文字列を表示するための練習として残しておきます。

CDROM filename = "MSCD000 " 
Array = 00 
Array = 00 
Array = 00 
Array = EF 
Array = 04 
Array = 00 
Array = 00 
Array = 00 
Array = 00 
Array = 00 
Array = 00 
Array = 00 
Array = 00 
Array = 00 
Array = 00 

Press a button to exit the program. 
:それは15バイトのデバッグダンプで完全な単語

#include <stdio.h> 
#include <conio.h> 
#include <dos.h> 
#include <string.h> 

//we'll superimpose this upon myarray 
struct CDINFO 
{ 
    unsigned char  subunit; 
    unsigned char far* pData; 
}; 

void CDname() 
{ 
    unsigned char myarray[15]; 
    int i; 

    //for debugging, ensure this buffer is initially clear 
    memset(myarray,0,sizeof(myarray)); 

    asm { 
     mov ax,1501h 
     lea bx,[myarray] 
     int 2Fh 
    } 

    //notice the %Fs format specified specifies a "far" string 
    printf("CDROM filename = \"%Fs\"\n", 
     ((CDINFO*)myarray)->pData + 10 
    ); 

    //this is useful for debugging 
    for(i=0; i<sizeof(myarray); i++) 
    { 
     printf("Array = %02X\n",myarray[i]); 
    } 
} 

void main() 
{ 
    clrscr(); 
    CDname(); 
    printf("\nPress a button to exit the program."); 
    getch(); 
} 

OUTPUTに> 127任意のバイトを符号拡張されたので、私はまた文字にunsigned char型からご使用のアレイタイプを変更し

更新:トラブルシューティング時に、私は最初にmyarrayをグローバル変数にし、 "mov bx、OFFSET myarray"を使ってアクセスしました。しかし私はSSがデータセグメントを指していることを認識していなかったので、myarrayがローカルのスタックベースのバッファとしてアクセスされるオリジナルに近いバージョンにソースを戻しました。

関連する問題