0

私のプロジェクト作業のために、コード スニペットをテストしました。そして、このコード スニペットは、スタックの使用によりセグメンテーション フォールトが発生することがわかりました。しかし、スタックを使用して解決する必要があります。誰でも問題を見つけるのを手伝ってもらえますか? 私のプログラムは、文字列変数の 2 番目の文字を表示します。私のコードスニペットは次のとおりです。

section.data
  string db "test",10,0
  msg2   db "%c",10,0
main:

xor eax,eax
mov eax, string
mov ebx,1    ; suppose I want to get the second character of string. SO I store the index of that character in ebx

pusha
push eax
push ebx
add esp,8
popa

pop dword[ebx]   ;  **I assume that this following 3 lines arise segmentation fault**   
pop eax          ;
mov bl,[eax+ebx] ; I want to move the fisrt character to BL using the index value stored in ebx which i popped just.

pusha
push ebx
call putchar
add esp,4
popa

pusha
push msg2
call printf
add esp,4
popa

念のため、このコード スニペットの目的はスタックの操作方法を理解することであることを明確にしたいと思います。

ここで、@nrz は最近、次のコードのアイデアを教えてくれました。ここで上記のコードを編集します。

  section.data
    string db "test",10,0
    msg2   db "%c",10,0
  main:
    xor eax,eax
    mov eax, string
    mov ebx,1  ; suppose I want to get the second character of string. SO I store the index of that character in ebx
    mov   eax,string
    movzx eax,byte [eax]
    push  eax        ; these push and pop are for solving it using the stack,
    pop   ebx
    pusha
    push ebx
    call putchar
    add esp,4
    popa
    pusha
    push msg2
    call printf
    add esp,4
    popa

私のクエリは具体的には次のとおりです。

  1. 指標値をあげます。登記簿に記載すべきebxですか?

  2. そして何よりも、スタックを使用する主なアイデアは、以前stringにプッシュしたインデックス値を使用して、変数のすべての文字にアクセスすることebxです。[それが必須です。出来ますか?]

  3. 出力を8ビットレジスタにも格納したい。

    だから私のすべてのアイデアは次のようなものです:

    mov al, [string+ebx]   ;is it possible?
    

    ebxスタックから値を取得する必要があります。に値を入力しebxpush ebxの時点で値mov al,[string+ebx]pop ebx取得してmov指示します。指示は次のようになります。

     pop ebx  
     mov al,[string+dword[ebx]]  ;which is a wrong statement shown by NASM
    

あなたの反応を楽しみに待っています。

ありがとうございました、

4

1 に答える 1

0

コードにはいくつかのバグと不要な指示があります。

移動 eax、文字列 ; この行は eax が文字列を指すようにしますが...
xor eax,eax ; この行は eax を即座にゼロにします。この行を削除します。
移動 ebx,1 ; この行は不要ですが、問題はありません。

プシャ。不要。
eax をプッシュします。不要。
ebx をプッシュします。不要。
esp,8 を追加します。不要。
ポパ; 不要。

pop dword[ebx] ; [1] = [esp]、esp = esp+4、おそらくセグメンテーション違反が発生します。
ポップ eax ; eax = [esp]、esp = esp+4
mov bl,[eax+ebx]

編集:すべての文字を出力するには、文字列をループするだけです:

セクション.データ
  文字列データベース「テスト」、10
  string_length equ $-string ; 文字列の文字数。
                             ; 文字列の末尾にゼロは必要ありません。
  msg2 データベース "%c",10,0
主要:
    xor eax,eax ; eax は文字列へのインデックスです。

char_loop:
    push dword [eax+文字列] ; 最初の 4 文字をスタックにプッシュします。
    および dword [esp], 0x000000ff ; x86はリトルエンディアンなので1文字目
                                 ; 最下位バイトです。
    ポップ ebx ; 文字の ASCII コードを ebx にポップします。

    プッシュカード
    ebxをプッシュ
    プッチャーに電話する
    esp,4 を追加
    ポパッド

    インクルーシブ
    cmp eax,string_length
    JB char_loop

編集:ebxインデックスとして使用して、質問の変更に一致する新しいコード。

セクション.データ
  文字列データベース「テスト」、10
  string_length equ $-string ; 文字列の文字数。
                             ; 文字列の末尾にゼロは必要ありません。
  msg2 データベース "%c",10,0
主要:
    xor eax,eax ; putchar のゼロ eax。
    xor ebx、ebx ; ebx は文字列へのインデックスです。

char_loop:
    ;push dword [ebx+string] ; 最初の 4 文字をスタックにプッシュします。
    ; および dword [esp], 0x000000ff ; x86はリトルエンディアンなので1文字目
    ; ; 最下位バイトです。
    ;ポップ eax ; 文字の ASCII コードを ebx にポップします。

    mov al,[ebx+string] ; これが通常の方法です。
                                  ; 上記の3つの命令は「スタックを使用して」実行します。
                                  ; 質問で要求されたとおりです。
    プッシュカード
    eaxを押す
    プッチャーに電話する
    esp,4 を追加
    ポパッド

    株式会社ebx
    cmp ebx,string_length
    JB char_loop
于 2013-03-17T08:39:02.347 に答える