1

cat>filenameシステムコールを使用して、Ubuntu 11.04 の NASM にコマンドを実装しようとしています。私のプログラムは正常にコンパイルされ、正常に実行されます (そう思われます)。しかし、cat filenameコマンドを起動しようとすると、「そのようなファイルまたはディレクトリはありません」と表示されますが、ディレクトリにファイルが存在することがわかります。ダブルクリックしてファイルを開こうとすると、「ファイルを開くために必要な権限がありません」と表示されます。私のコードのエラーを見つけるのを手伝ってくれませんか?

コードは次のとおりです。

section .data
   msg:     dd "%d",10,0    
   msg1:    db "cat>",0
   length:  equ $-msg1
section .bss
   a    resb 100
       len1 equ $-a
   b    resd 1
   c    resb 100       
   len2 equ $-c
section .txt
  global main
main:
  mov eax,4   ;;it will print cat>
  mov ebx,1
  mov ecx,msg1
  mov edx,length
  int 80h
start:
  mov eax,3   ;;it will take the file name as input
  mov ebx,0
  mov ecx,a
  mov edx,len1
  int 80h

  mov eax,5   ;;it will create the file by giving owner read/write/exec permission
  mov ebx,a
  mov ecx,0100  
  mov edx,1c0h
  int 80h

  cmp eax,0
  jge inputAndWrite
  jmp errorSegment

inputAndWrite:
  mov [b],eax   

  mov eax,3   ;;take the input lines
  mov ebx,0
  mov ecx,c
  mov edx,len2
  int 80h

  mov edx,eax   ;;write the input lines in the file
  mov eax,4
  mov ebx,[b]
  mov ecx,c
  int 80h   

  jmp done  
errorSegment:   
  jmp done
done:   
  mov eax, 1 
  xor ebx, ebx 
  int 80h 

ps 上記のコードは、RageD からの提案を取り入れて再編集されています。それでも、私が作成したファイルには、「inputAndWrite」セグメントから与えられた入力行が含まれていません。私はあなたの提案を探しています。

4

1 に答える 1

3

アクセス許可に関する主な問題は、アクセス許可が にoctalあり、それらを にリストしたことですdecimal0700基数 10 ではなく、基数 8 で探しています。代わりに、 1c0h( 070016 進数で 8 進数) を使用してみてください。したがって、次のコード修正により、アクセス許可の問題が修正されるはずです。

;; This is file creation
mov eax, 5
mov ebx, a
mov ecx, 01h ; Edited here for completeness - forgot to update this initially (see edit)
mov edx, 1c0h

参考までに、Linux システム コールのクイック ガイド (少し古いかもしれませんが、ほとんどの場合は正しい) はLinux System Call Tableを使用することです。レジスタの設定方法などを覚えるのに非常に役立ちます。

もう 1 つの重要な問題は、ファイルへの書き込みです。いくつかの問題で少し混乱したと思います。まず、長さ変数に注意してください。アセンブリは「インライン」で行われます。つまり、len1 を計算するときは、 間の距離と 間aのすべてを計算alen1ます。つまり、長さの値は次のようになります。

.section bss
a resb 100
len1 equ $ - a
b resd 1
c resb 100
len2 equ $ - c

これを行うと、適切な読み取りが行われるようになります (ただし、入力用のバッファー サイズによって制限されることに注意することが重要です)。

私が見つけたもう 1 つの重要な問題は、ファイルへの書き込み方法です。syscall レジスタを反転しました。

;; Write to file
mov edx, eax ;; Amount of data to write
mov eax, 4 ;; Write syscall
mov ebx, [b] ;; File descriptor to write out to (I think this is where you stored this, I don't remember exactly)
mov ecx, c ;; Buffer to write out

ここから、さらにいくつかの調整を行います。まず、うまく終了するために (segfault なしで)、単純に を使用することをお勧めしexitます。これが別のプログラムにない限り、ret(特にこれがスタンドアロンの x86 プログラムである場合) 常に正しく動作するとは限りません。exit syscall のコードは次のとおりです。

;; Exit
mov eax, 1 ;; Exit is syscall 1
xor ebx, ebx ;; This is the return value
int 80h ;; Interrupt

また、清潔さに関しては、改行でバッファリングされた入力を取っていると思います。この場合、ファイル名の後の改行文字を削除することをお勧めします。これを行う最も簡単な方法は、最後の文字 (改行になります) の後で単純に null で終了することです。したがって、ファイル名の入力を読み取った後、次のようなコードを配置します。

;; Null-terminate the last character - this assumes it directly follows the read call
;; and so the contents of eax are the amount of bytes read
mov ebx, eax ;; How many bytes read (or offset to current null-terminator)
sub ebx, 1 ;; Offset in array to the last valid character
add ebx, a ;; Add the memory address (i.e. in C this looks like a[OFFSET])
mov BYTE [ebx], 0 ;; Null-terminated

最後に、大規模なプロジェクトでは、完了したらファイル記述子を閉じるのが礼儀です。すぐに終了するため、ここでは必要ないかもしれませんが、次のようになります。

;; Close fd
mov eax, 6 ;; close() is syscall 6
mov ebx, [b] ;; File descriptor to close
int 80h

編集

すみません、書き込み問題を見逃していました。value でファイルを開いています100。必要なのは1O_RDWR読み取りおよび書き込み機能)です。また、syncシステム コール (0x24引数なしのシステム コール番号) を使用して、バッファが適切にフラッシュされるようにすることを検討することもできます。ただし、私のテストでは、データを入力するための改行が技術的にこれを行う必要があるため、これは不要でした。したがって、ファイルを適切に開くための更新コードは次のようになります。

; Open file
mov eax, 5
mov ebx, a
mov ecx, 01h
mov edx, 1c0h
int 80h

お役に立てれば。幸運を!

于 2013-04-10T01:35:12.757 に答える