4

したがって、ほとんどのコードは機能していますが、入力文の長さが不明であるという事実をどのように正確に処理するかを理解することはできません。私はアセンブリに不慣れで、これはすべて少し混乱しています。

(現在、長さが3文字であることがわかっているかのように設定していますが、明らかにそれを変更する必要があります。)

.data       
input_msg:  .ascii "Enter a random sentence: "
input_msg_len:  .long 25
input_str:  .ascii  "???" # 3rd should get newline  
count:      .long 0 
newline:    .long 10    

.text               
.global _start          
_start:             

# prompt for input
    mov $4, %eax    # prompt for input
    mov $1, %ebx
    mov $input_msg, %ecx
    mov input_msg_len, %edx
    int $0x80
# get input
    mov $3, %eax    # 3 to request "read"
    mov $0, %ebx    # 0 is "console" (keyboard)
    mov $input_str, %ecx # input buffer addr
    mov $3, %edx    # number of symbols typed in
    int $0x80       # Go do the service!

again1:
    mov $input_str, %ecx    
    add count, %ecx # count is offset from input_str beginning

    mov $4, %eax    # to write
    mov $1, %ebx    # to console display
    mov $1, %edx    # 1 byte to write
    int $0x80   # Do it!

    push    %ecx        # push onto stack   

    incl    count   # increment count

    cmp $3, count   # compare lengths
    jnz again1     # jmp again if not 0 (no difference)

    mov $0, %edi    # use edi as loop counter

    mov $4, %eax    # print out msg
    mov $1, %ebx    # etc.
    mov $1, %edx    # length
    int $0x80       # OS, serve!

again2:     
    pop %ecx    

    mov $4, %eax    # print out msg
    mov $1, %ebx    # etc.
    mov $1, %edx    # length
    int $0x80       # OS, serve!        

    inc %edi    # increment edi 
    cmp count, %edi # compare lengths
    jnz again2  # jmp again if not 0 (no difference)

# print newline
    mov $4, %eax    # print out msg
    mov $1, %ebx    # etc.
    mov $newline, %ecx  # addr
    mov $1, %edx    # length
    int $0x80       # OS, serve!
# exit
    mov $1, %eax    # exit
    int $0x80       # OS, serve!    

基本的に、私が知りたいのは、3文字の長さだけでなく、どの文に対してもコードを機能させる方法です。

4

2 に答える 2

0

input_str読み取りシステムコールに続くeaxにある、効果的に読み込まれたテキストの量を読み取るために、より長いバッファを割り当てる必要があります。

つまり、受け入れる最大長を決定し、コードを次のようなものに変更する必要があります。注:もちろん、大きなバッファーが必要な場合は、静的
に このような短い文字列を割り当ててもかまいません(たとえば、ファイルからデータを取得します)、代わりにバッファを動的に割り当てることができます)。繰り返しますが、キーボード入力には132がおそらく適切です。

...
input_str:  db  132 dup(?)  # 132 bytes buffer for input string
input_str_len: .long        # length of the string effectively read from user
...
# get input
    mov $3, %eax    # 3 to request "read"
    mov $0, %ebx    # 0 is "console" (keyboard)
    mov $input_str, %ecx # input buffer addr
    mov $131, %edx    # _Max_ number of bytes accepted in input_str
    int $0x80       # Go do the service!

    move %eax, $input_str_len    # save nb of bytes effectively read
...
    #you can then use input_str_len to control when to exit processing loop etc.
于 2013-03-16T04:39:58.057 に答える
0

ええと...あなたは=0でsys_brkを行うことができます。%ebxそれはあなたの元の「休憩」です-それを保存してください。その値に4kの倍数を追加し、sys_brkを再度追加します。そのバッファにsys_readを実行します。(sys_readの後に)4k全体を読んだ場合は%eax、現在の「ブレーク」とsys_brkにさらにいくつか追加してから、完了するまでさらに読んでください。これは、すべてを1つの連続したバッファーに「すべき」です...

いくつかの「最大」を決定するだけで、それ以上入力させないでください。「バッファをフラッシュする」ことをお勧めします。ご存知のように、(キーボードからの)sys_readは、改行(0xA)が表示されるまで戻りません。厄介なユーザーが複数の%edx文字を入力した場合、残りはOSのバッファーに残ります。これは、3バイトのバッファコードで確認できます。「abcls」と入力します。「ls」は、終了後にシェルプロンプトによって読み取られ、ディレクトリリストが表示されることがわかると思います。問題ありませんが、「rm」または何か有害な可能性があります。sys_readが戻ったときに、%eaxが未満%edxの場合は完了です。%eax=の場合%edx(それ以上になることはありません)、バッファの最後の文字がLF(0xA)の場合、これで完了です。そうでない場合は、そのLFを取得するまで、sys_readをダミーバッファに入れます。これはコードを非常に複雑にしますが、「より安全」です...

Nasm構文の例を試すことはできますが、AT&Tを試してみたほうがいいとは思いません... :)

于 2013-03-16T15:41:27.810 に答える