2012-02-23 11 views
2

0xffバイトをパラレルポート0x378に書き込もうとしています。問題なくコンパイルしてリンクしますが、OUTSB命令ではセグメンテーションが失敗します。Linux NASM OUTSB SegFault

section .text 
     global _start 

_err_exit: 
     mov  eax, 1 
     mov  ebx, 1 
     int  80h 

_start: 
     mov  eax, 101  ; ioperm 
     mov  ebx, 0x378 ; Parallel port addr 
     mov  ecx, 2  ; number of bytes to 'unlock' 
     mov  edx, 1  ; enable 
     int  80h 

     mov  esi, 0xff 
     mov  dx,  0x378 
     outsb 

     mov  eax, 1  ; exit 
     mov  ebx, 0 
     int  80h 

私はGDBでそれをステップ実行し、ちょうどOUTSB命令の前にレジスタをチェックするとDXレジスタに何かがあるように、それは見ていないのですか?またはdx == edx(32ビット)?

(gdb) info registers 
eax   0x0 0 
ecx   0x2 2 
edx   0x378 888 
ebx   0x378 888 
esp   0xffffd810 0xffffd810 
ebp   0x0 0x0 
esi   0xff 255 
edi   0x0 0 
eip   0x8048090 0x8048090 <_start+36> 
eflags   0x246 [ PF ZF IF ] 
cs    0x23 35 
ss    0x2b 43 
ds    0x2b 43 
es    0x2b 43 
fs    0x0 0 
gs    0x0 0 

私はここで間違っていますか?

(OUTS命令の情報:http://siyobik.info/main/reference/instruction/OUTS%2FOUTSB%2FOUTSW%2FOUTSD


EDIT:プログラムの

Cのバージョンは動作します:

int main(int argc, char *argv[]) 
{ 
    int addr = 0x378; 
    int result = ioperm(addr,5,1); 

    outb(0xff, addr); 

} 

答えて

4

そのコードを持つ多くの問題があります。まず、OUTSBが特権命令であることを忘れているように見えます。つまり、呼び出し元プロセスに呼び出し0のアクセス権がある場合、つまりカーネルコードの一部である場合にのみ実行できます。私の知る限り、特権命令にアクセスできるLinuxの唯一のコードは、カーネル自体と、ロードするモジュールです。特権を持たないコードセグメントから特権命令を実行しようとすると、他のすべてのプロセスはSegmentation fault(実際にはCPUによってシグナルされるGeneral Protection Fault)を返します。しかし、私はiopermを呼び出すことによってどのように影響を受けるのか分かりません。

第2に、OUTSBは、ESIで指定されたメモリ位置から、DXのI/Oポートにバイトを書き込みます。この場合、プロセスに確実にアクセスできない場所0xffからポートにデータを書き込むようにプロセッサに指示しています。 OUTSBは、接頭辞REPで使用することを意図しているため、OUT命令を使用するようにコードを変更するだけで簡単にすることができます。これを試してみてください:

mov al, 0xff 
out 0x378, al 

これは、この場合0x378には、即値オペランドで指定されたI/Oポートにalでバイトを出力します。

私はそれがどのように判明したか教えてください。

+0

もう1つ注意してください:Intelマニュアルの一部を改訂しました。個々のI/Oポートに個々のタスクに対する権限を与えることは明らかです。これは、OSでTSS(Task State Segment)構造を使用する必要があり、Linuxが個々のプロセスにそれを使用するかどうかはわかりません。 –

+0

'OUT'は' OUTS * 'と同じ特権を持ち、一方を他方に置き換えても主な問題は解決しません。 –

+1

私はそれを知っています。しかし、この場合の 'OUTSB'は、プロセスのアドレス空間に存在しないメモリ領域からの読み出しを引き起こすため、不適切に使用されます。 –