• ベストアンサー

ファイルポインタ

HDDを先導から終端までを0で埋めるものを作りたいのですが それってCの許容を超えてるのでしょうか? (アセンブラじゃないと無理?) ファイルポインタについてよくわからないのですが ファイルポインタのさすアドレスは 相対的なものなのでしょうか? あとアセンブラでは8086アセンブラやMASMという言葉をよく聞きますが そちらについてもご存じであればご教授ください。

質問者が選んだベストアンサー

  • ベストアンサー
  • k-family
  • ベストアンサー率34% (180/523)
回答No.4

HDD廃棄用ソフトを作るのが目的でしょうか?もし、そうであれば下記の回答は意味がありませんが、目的については触れないで回答します。 1)”普通の方法では”「HDDを先導から終端までを0で埋める」ことはできません。ファイルに対してのアクセスはできますが、HDDへの直接のアクセスはできません。(あくまで、普通は、です) ファイルの先頭から終端までなら0で埋めることはできます。 2)Cのファイルポインタはlong(signedだったかも)ですのでその範囲でアクセスできます。 3)ファイルポインタのさすアドレスは、相対と絶対がありますが、どちらにしてもファイルの中の話です。HDD中のファイルの位置は”普通では”わかりません。そういう意味では相対です。 4)「HDDを先導から終端までを0で埋めるもの」、そのようなソフトを作ることはCで可能です。ですが、Windows上で作ることは「許容を越えて」います。 つまり、WindowsではHDDの様なハードウエアを直接触ることはできないようになっています。間違えればOS自体が飛んでしまうからです。 直接操作したいと言うことであれば、この質問を終えて、具体的に別の質問をされると良いと思います。 ----- アセンブラはCPUの種類に応じて(対応して)存在します。8086というのはインテルのCPUで、元祖(色々な意見があると思いますが)PCに使われていたCPUです。その8086CPU用のアセンブラです。 (以下は多少誤りを含む可能性があります) MASMは商品名ですが、MacroASseMblerから来ています。マクロが使える8086対応アセンブラです。たぶん現在は8086だけではなくP4くらいまで対応しているのではないかと思います。←このあたりは推測です。

sha-girl
質問者

お礼

具体的にはフロッピーから起動して、そこからHDDを復元不可能な状態にしたいのです。OSはWindows上じゃなくてもいいです。 勉強になりました。ありがとうございます。

その他の回答 (8)

  • itohh
  • ベストアンサー率45% (210/459)
回答No.9

こんにちは。itohhといいます。 >その場合だと大容量のHDDの場合MS-DOSの扱える上限以下でパーテーションをきると >いうことでしょうか。 パーテーションまでは、考えていませんでしたが、そういうことになると思います。 コピーを実行するプログラミング的にはそんなに難しくないですよね?

sha-girl
質問者

お礼

レスありがとうございます。色々な方法を検討かつ勉強していきたいと思います。 お答えくださった皆様、本当にありがとうございました。

  • itohh
  • ベストアンサー率45% (210/459)
回答No.8

こんにちは。itohhといいます。 >具体的にはフロッピーから起動して、そこからHDDを復元不可能な状態にしたいのです。 目的は、「HDDを復元不可能な状態」にしたいということなら、以下の案は如何ですか? (1) 1MB程度のファイルを用意する。 (2) HDDをFDISK&FORMATを済ませた状態にする。 (3) (1)で用意したファイルをHDDがいっぱいになるまでファイル名を変更しながらコピーする。 batファイルだけで行えるかは、ちょっと自信がないのでDOSで動くように16ビットアプリを 作成することをお薦めします。。 今現在、16ビットアプリを作成できるコンパイラーは「LSI C-86」しかないと思います。 もしかしたら、DOSでは1ディレクトリ上に置けるファイル数に上限があるかもしれません。 (ちょっと忘れてしまいました) もし、上限がある場合は、適当にサブディレクトリを作ってファイルをHDDがいっぱいになるまで コピーすることになると思います。 細かいロジックは省きましたが如何でしょうか? 最後に「LSI C-86」に関係するサイトを載せておきます。 「LSI C-86 ダウンロード」 URL:http://www.vector.co.jp/soft/maker/lsi/se001169.html 「LSI C-86 開発環境(きときと-CPad)」 URL:http://hp.vector.co.jp/authors/VA017148/pages/cpad.html

参考URL:
http://www.vector.co.jp/soft/maker/lsi/se001169.html,http://hp.vector.co.jp/authors/VA017148/pages/cpad.html
sha-girl
質問者

お礼

レスありがとうございます。その場合だと大容量のHDDの場合MS-DOSの扱える上限以下でパーテーションをきるということでしょうか。

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.7

>具体的にはフロッピーから起動して、そこからHDDを復元不可能な状態にしたいのです。OSはWindows上じゃなくてもいいです。 LinuxやFreeBSDのようなOSだとコマンドでも可能です。 おおまかに言えば、FDブートなどでHDDをマウントせずにブートし、 HDDデバイスをファイルシステムでなくrawデバイスとしてアクセスして書き込めば実現できたと思います。 これはHDD全体を一つのファイルとしてアクセスするようなものなので、通常のファイルアクセスでHDDを埋め尽くすことが可能になります。 多分fopen系の関数でも問題無いような気が。 まあ、open系なら可能でしょう。 windows系のOSではこういうアクセスの方法が無いのでできないでしょう。 というか、FDだけで動かすという時点でWindowsはアウトですが。 FDで動作するLinuxのディストリビューションを使うか、 インストール用のFDの中身を細工(必要なコマンド、プログラムを追加し、インストーラーを起動せずshellを起動する等)すれば 可能なはずです。 コマンド自体は dd if=/dev/zero of=/dev/hdd....のような感じでいけるかと。 まあ、実際に使う際はよく調べてからどうぞ。 hddのデバイス名とか,ddコマンドのパラメタとか。

sha-girl
質問者

お礼

Linuxでそういうコマンドがあるんですね。その方面でも色々調べてみます。ありがとうございました。

  • k-family
  • ベストアンサー率34% (180/523)
回答No.6

やはり、そういう目的なんですね。 先の回答で、目的に触れない、と言ったのは、その目的を実現するだけならもっと簡便な方法がいくらでもあるからなのです。 この想定される目的と、質問内容から、失礼ながらsha-girlさんの経験を推定して先のような回答をしました。良く読んでいただれればわかると思いますが、”普通は”とか、そのような表現を多用しているのはそのためです。 ------ >具体的にはフロッピーから起動して そこまで考えられているのならなんでもできます。Cだけでできないことであってもアセンブラとリンクすればいいわけですから。 ただ、fopenのような関数はOSの機能を利用しているので、ファイルポインタで簡単に済ますのは難しいです。自分でHDDアクセス関数を作る必要があります。BIOScallを使う必要がありますが、可能です。

sha-girl
質問者

お礼

勉強する事がいっぱいありますね。ありがとうございました。

  • KOH_da
  • ベストアンサー率31% (161/506)
回答No.5

HDDの読み書きには、論理的に行なうものと、 物理的に行なう方法があります。 普通の読み書きは、すべて論理的なものです。 これはファイルシステムを通して処理するので、 FAT(ファイル名や、ファイルの配置を記録するとこ)で 表された部分しか読み書きできません。 物理的に読み書きするには、 そのHDDをアクセスするための方法を調べ、 その手順に従えば可能です。 またその処理ルーチンは、BIOSとして用意されており、 そのコマンドをBIOSに対して順に送ればいいことになります。 たとえばfdiskや、formatというコマンドは、 そのように作られていると思います。 もちろんC言語だけで開発できると思います。 ただ開発途中で、その手順を間違えてしまうと、 開発していたHDDの内容も消してしまいます。 正直なところ、sha-girlさんには荷が重いと思いますが、 参考文献を紹介しておきます。 CQ出版社 パソコンのレガシィI/O活用大全 桑野 雅彦著 定価1,800円 読むべきページは p.108くらいからですかね。 特にp.110をながめれば、約2秒で挫折を味わうかと思います。 □k-familyさん >WindowsではHDDの様なハードウエアを >直接触ることはできないようになっています。 HDDを消すために、そのソフトをHDDから起動するとは思えません。 FDDから起動するプログラムを記述するとすれば、 OSなんて関係ないような気がします。 また、WindowsNT/2000/XPはどうだか知りませんが、Windows95/98/Meではハードウエアを、 自由に操作することができますよ。 その後OSに戻って来れる保証はありませんが。

sha-girl
質問者

お礼

書籍の紹介ありがとうございます。早速注文しました。アセンブラについても勉強しようと思います。

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.3

honiyonさんの書いた方法だとうまくいきません。 1. ファイルとして書ける部分はHDDの全体ではない。 例えば,ファイル名,ファイルのタイムスタンプが保存されている部分はこの方法では消すことができません。 alicia-yさんが書いているような方法でないと無理です. 2. エラーが出るまでゼロを追記書き込みしていっても、 HDDを埋め尽くすことはできない可能性がある。  使っているOSやファイルシステムによりますが、 たとえばファイルサイズが最大2Gの制限がある場合、 パーティションが2G以上あれば,おそらく2Gを超えた部分には  何も書き込まれません。

sha-girl
質問者

補足

そういえばfat32だとファイル2Gの壁とかありましたね。 参考にさせて頂きます。ありがとうございます。

  • alicia-y
  • ベストアンサー率40% (85/208)
回答No.2

OS やハード等の環境がわからないので適切な回答をすることが出来ませんが、 ご使用の OS にハードディスクにローレベルでアクセス出来るインターフェースが あれば可能です。 PC AT互換機などであれば BIOS の機能を使って行うことも出来ます。 (BIOS のメニュー画面でということではない) 開発言語から上記のようなインターフェースを使用できるならどんな言語を使っても 出来ます。

sha-girl
質問者

お礼

ありがとうございます。 具体的にCでBIOSの機能を使うにはどうすればいいのでしょうか? あと気になるのはBIOSを呼び出したとき、BIOSのメーカーに依存するのでしょうか?

  • honiyon
  • ベストアンサー率37% (331/872)
回答No.1

こんにちは、honiyonです。  HDDの空き領域を全てゼロで埋め尽くしたいという事でしょうか?  それでしたら...    1.ファイルを新規作成して開く    2.エラーが出るまでゼロを追記書き込みしていく。    3.ファイルを閉じる。  で可能だと思います。  但し、この方法ですと処理が終了するまで非常に時間がかかるので、それを改善するには少し工夫が必要になってきます。  参考になれば幸いです(..

sha-girl
質問者

お礼

レスありがとうございます。参考にさせていただきます。

関連するQ&A

  • masm32がうまく動きません。

    アセンブリ言語を学ぼうとmasm32をインストールしました。 インストール手順は下記のように行いました。 ・masm32を C:\ にインストール ・masm32のbinフォルダの中にあるlink.exeをlink32.exeに名前を変更し、16bitリンカLINk.exeをbinフォルダに投入 ・システム環境変数に SET PATH=C:\MASM32\BIN;%PATH% SET INCLUDE=C:\MASM32\INCLUDE;%INCLUDE% SET LIB=C:\MASM32\LIB;%LIB% を書き加える。 ソースをC:\に保存し、アセンブラしてみると C:\>ml /c /Fl test.asm 'ml'は内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチファイルとして認識されていません。 と出ます。 ソースの保存場所をC:\masm32\binに変えて C:\masm32\bin>ml /c /Fl test.asm の形でアセンブラすることはできます。 ソースをC:\に保存した状態でアセンブラできない原因は何が 考えられるでしょうか?

  • アセンブリ言語について教えて下さい。no.2

    ご覧いただきありがとうございます。 前回の質問に続き、アセンブラについてお聞きしたいと思います。 前回ご回答を下さった方には非常に感謝しております。またよろしくお願いいたします。 「page擬似命令」と「2つのファイルをリンクさせる方法」が知りたいのですが、参考書等を拝見してもよくわかりません。 どなたかご教授下さい。 ちなみにアセンブラは8086のMASMです。 よろしくお願いいたします。

  • ポインタ演算がうまくできません

    以下のソースを実行すると、直値でアドレスをしていするのは うまくアセンブラに展開され、意図するアドレスを取り出す ことが出来るのですが、変数でアドレス演算させると意図する アドレスが取得できません。  何か記述がおかしいのでしょうか? ご存知の方宜しくお願い致します。 char const test_tbl[] = { -3, -2, -1, 0, 1, 2, 3, 4, 5}; unsigned char *ptr; unsigned char work; #define STA_OFFSET (&test_tbl[3]) void main( void) { // 適切なポインタが取得できる ptr = (STA_OFFSET + 3); // ポインタが取得できない。 work = 3 ptr = (STA_OFFSET + work); }

  • アセンブリ言語のラベルについて

    MASMアセンブラを使ってアセンブリ言語の勉強を始めました。 ラベルについてなのですが、以下のようなコードがあります。 msg db "ABCD" これは、msgという名前でメモリに4バイト確保して文字列で初期化するということだと分かりました。 そこで質問なのですが、msgというのはこの文字列の先頭アドレスを表すということですが、このmsgは上記の"ABCD"のようにメモリに領域を確保されて保存されているものなのでしょうか(C言語のポインタのようなもの)。 それとも、即値のように直接ソースコード上に書かれているものなのでしょうか。(つまり、アセンブルをするとソースコード上のmsgが"ABCD"の先頭アドレスに置き換わるようなことがおこるのでしょうか) 言葉足らずですみませんが、よろしくお願いします。

  • ポインタ変数とポインタのポインタ

    ポインタ変数の宣言 char *a[]; をしたとき僕の中では a[0],a[1]...という、ある文字列A,B,C...の最初のアドレスを指すポインタが、配列になっているものを宣言していると理解していました。 しかしこの次に、ポインタのポインタが出てきました。僕はこれを、 ある変数を指し示すアドレスのアドレスである、と理解しました。 この2つは1つめはいくつかのアドレスを指し示すもの、2つ目は1つのアドレスを指し示すものであるとして、僕の中で異なったものであると理解していましたが、参考書「C標準コースウェア」によると プログラムにおいて、関数でポインタ配列を受け取るときchar *p[]はchar **pとしてもよい と書かれており、またその実例として、 (9-5) #include <stdio.h> void disp (char *p[],int n){ int i; for (i= 1;i<n;i++){ printf("%s\n",p[i]); } } int main(void){ char *girl[] = {"Arica","Candy","Lisa"}; disp (girl,sizeof(girl)/sizeof(girl[0])); return 0; } というプログラムが書かれていました。 ここで一気に訳が分からなくなりました。 char *girl[] = {"Arica","Candy","Lisa"}; と宣言されているため、 girl[0]はAricaという文字列の最初のアドレスを指すポインタ、 *girl[0]はAricaという文字列を直接指し示していると解釈しています。 girlは{"Arica","Candy","Lisa"}という文字列の配列の最初のアドレスを指し示していると考えました。 sizeof(girl)を使った時に不思議なのですが、 girlはどのように配列の終わりを理解しているのでしょうか? (配列の要素数を渡していない点が不思議です。) また、 disp側が受け取ったのは*girl[]であり、いくつかのポインタの配列ですが、渡したものはgirlという要素数がないポインタ1つだけです。 そして最初の疑問が出てくるわけですが、*p[]を**pと書きかえてみると、 文字列のアドレスを示すgirlという名の1つのポインタを渡すと、pという名のポインタのポインタで受け取るというのも、よくわからなくなっています。 おそらくポインタ配列に対する理解がどこかでずれているようですが、自分でどこがわからないのかわからなくなっています。 どうかご教授ください。

  • ポインタについてアドバイスお願いします。

    C言語の初心者です。 参考書でも書かれている事があるのですが、経験豊富な方でもポインタについて知ってるようで知ってないということがあります。って読んだことがあります。 実際、ポインタの必要性とはどのような時に必要なのでしょうか?? アドレス指定と言う風に、はじめはこの様な理解から入ると習いましたが、私には配列で十分間に合うのでは??って思っちゃうのです。 構造体の出力、アドレスの入れ替え、こんなときには便利なのかもしれませんが、C言語をやる上で絶対に必要・・、いったいなぜ??って考えちゃいます。 初心者なのに生意気な事言ってしまってもうしわけございません。 以前、私もそんな感じで悩んだ事あるって方がいらっしゃいましたら、ポインタとはこんな感じの時に初めて必要だと思うのだ!とご教授お願いいたします。 この様な質問に対しても、笑って答えてくださるような プロフェッショナルの方や、一般の凄い方のアドバイス、お待ちいたしております。 宜しくお願いいたします。

  • アセンブラでの記述について教えてください。

    アセンブラでの記述について教えてください。 CMDでのアセンブリで、 mov dx , [0200] (0200へは'ab'を代入しておく) mov [0400] , dx とすれば0400番地へabが複写されるのですが、これをmasmで mov dx , data1 mov data2 , dx data1 db 'ab' data2 db '00' とすれば「invalid instruction operands」というエラーが生じます。 dataのアドレス値を他に格納してから複写すると上手くいくのですが、お聞きしたいのは上記の違いです。 [0200]はmasmだと data1 また、 [0400]はmasmだと data2  実際のアドレス値は当然違いますが、これは理屈的に同じとならないのでしょうか? なぜmasmの場合だと、 mov si , offset data1 mov di , offset data2 mov al , [si] mov [di] , al などのように、わざわざアドレス値を用いて遠まわしにしなければならないのでしょうか? どなたかご教授のほどをお願いします。

  • FILE構造体のファイルポインタについて質問です。

    FILE構造体のファイルポインタについて質問です。 Microsoft VC++を使っています。 テキストファイル(1行の連続して文字が連なっている。)のn文字目からの文字を読み取る場合、fgetsでn-1文字目まで読み取ってから、fgetsでn文字目から読み取ればできるのですが、ファイルポインタを使用した場合について教えてください。 FILE *fp; fp = fopen("a.txt","r"); と宣言すると、fp->_ptrがファイルポインタになります。 この段階でfp->_ptrは0で、値を読み込みとエラーになります。(ファイルの実行が停止) fgets()で何文字でもいいから読み込むと、fp->_ptrにアドレスが読み込まれます。 fp->_ptrに加算してn-1文字目まで動かして、fgetsで文字を読み込めば読み込めるのですが、 ファイルの残りの文字数よりも読み込む文字数が大きい場合、その差分だけへ(アスキーコード205) が読み込まれます。 詳しく説明すると、テキストファイルにn文字目からabcdeという5文字があるとします。 n文字目から10文字読み込んだ場合、配列に格納される文字がabcdeヘヘヘヘヘになってしまいます。 へ(アスキーコード205)の数は最大でfp->ptrに加算した値となっています。 質問としましては (1)fp->ptrにアドレスが書き込まれるのはどのタイミングなのでしょうか? (2)なぜへ(アスキーコード205)が格納されてしまうのか? 分かる方、是非ご教授をよろしくお願いします。

  • ポインタで分からないことがあります。

    つい最近C言語の勉強を始め、現在ポインタの勉強をしています。 過去の質問を検索したり、サイトを見てみましたが、一人の力では解決できませんでしたので質問させていただきます。 ポインタのプログラムで、下記のプログラムについて分からないことがありました。 ――――――――――――――――――――――――――――――――― #include <stdio.h> int main (void) { char *str = "abc"; printf ("%s %d %d\n", str, &str, &(*str)); str = "日本語"; printf ("%s %d %d\n", str, &str, &(*str)); return 0; } ――――――――――――――――――――――――――――――――― このプログラムで、「char *str = "abc";」の部分でstrには abcのアドレスが入っていると思っていたのですが、 1度目の「printf ("%s %d %d\n", str, &str, &(*str));」で、 結果が「abc 1245064 4235560」となっているのを見ると 私の見解は間違っている気がします。 「char *str = "abc";」の部分では一体なにが行われているのでしょうか? また、このプログラムをコンパイルして実行した結果が、 abc 1245064 4235560 日本語 1245064 4235574 となったのですが、なぜstrのアドレスは同じなのに、 &(*str)のアドレスは異なるのでしょうか? 質問をまとめますと、以下の2つです。 1.「char *str = "abc";」の部分では一体なにが行われているのでしょうか? 2.「abc」と「日本語」のstrのアドレスは同じなのに、&(*str)のアドレスは異なるのでしょうか? 初心者ですので言葉の足らない部分があるかもしれませんが、ご教授のほどよろしくおねがいします。

  • ポインタ演算

    http://wisdom.sakura.ne.jp/ このサイトの講座から引用 *po++; とやると、多くの人の期待に反した結果が得られると思われます このときは、アドレスが指す変数ではなくポインタの値がインクリメントされてアドレスを参照されます とありますが、実際に実行してみると、インクリメントされた後に参照 されます。なぜでしょうか、ご存知の方は回答お願いします。 OSはWindows コンパイラはBorland C++ Compilerです。

専門家に質問してみよう