2016-12-10 12 views
1

私は比較的新しいアセンブリです.2つのコマンドライン引数を入力(2番目のコマンドライン引数は文字列)とし、その長さを1から30の間でチェックするプログラムを作成しようとしています。文字列が文字0,1、および2のみで構成されているかどうかを確認してください。他の文字はすべて終了し、終了します。プログラムを実行すると、単に "Segmentation fault"が出力されます。集まったiveから、私が嫌うべきではない記憶の部分を扱っているときにこれが起こります。私は自分の問題がループ内のどこかにあることを知っていますが、どこか理由はわかりません。私のコードが間違っている場所についてのご意見は、大変ありがとうございます。NASMアセンブリー:文字列+確認文字列の長さをチェックするのは '0'、 '1'、 '2' 'のみです。

%include "asm_io.inc" 
global asm_main 

SECTION .data 
    lenError: db "Length of string must be between 1 and 30 (inclusive).",10,0 
    argError: db "Only 2 command line arguments accepted.",10,0 
    charError: db "Only characters '0', '1', and '2' are accepted.",10,0 

SECTION .text 
    global asm_main 
    extern strlen 
    extern printf 

asm_main: 
    enter 0,0 
    pusha 
    mov eax, dword [ebp+8]  ; argc 
    cmp eax, dword 2    ; if argc == 2 
    jne ERR_ARG 
    popa 
    mov ebx, dword [ebp+12] 
    mov eax, [ebx+4]   ;eax has the string in it now 
    mov ecx, 0    ;initialize a counter 
    LOOP1: 
    cmp byte[eax], 0  ;end of string 
    je DONE 
    cmp byte[eax], '0'  ;check if char == 0 
    je GO 
    cmp byte[eax], '1' 
    je GO 
    cmp byte[eax], '2' 
    je GO 
    jmp ERR_CHAR 
    GO: 
    inc ecx  ; increase counter 
    inc eax  ;next position in string 
    cmp ecx, 30 
    jg ERR_LEN 
    jmp LOOP1 

    DONE: 
    call print_string  ;there's more to come, 
    jmp asm_main_end  ;but i want to find the error first 

    ERR_CHAR: 
    mov eax, charError 
    call print_string 
    jmp asm_main_end 
    ERR_LEN: 
    pop eax 
    mov eax, lenError 
    call print_string 
    jmp asm_main_end 

    ERR_ARG: 
    mov eax, argError 
    call print_string 
    jmp asm_main_end 

    asm_main_end: 
     popa 
     leave 
     ret 

UPDATE:ここ

コードだ私はasm_main_endにセグメンテーションフォールトを単離したと信じて、私はプログラムから終了していますどのように何か問題はありますか?

+1

デバッガをステップ実行すると、何が見つかりますか? –

+0

申し訳ありませんが、デバッガの使い方を教えてください。私はこのすべてのものに新しい。 – user7275873

+1

デバッグは非常に簡単に答えられるものではありません。あなたがコースを受講している場合は、教授や教師の助手に相談してください。デバッグに関する情報を要求することができます。 –

答えて

3

セグメンテーションフォルトの原因となる問題は、機能開始時のjne ERR_ARGの後のpopa命令です。分岐が取られない場合、レジスタはそこでスタックからポップされ、その後再びasm_main_endにポップされます。

asm_main: 
    enter 0,0 
    pusha 
    mov eax, dword [ebp+8]  
    cmp eax, dword 2  
    jne ERR_ARG 
    popa     ; Do not pop here 
    ; 
    ; 
    ; 
    asm_main_end: 
     popa    ; when popping here 
     leave 
     ret 

popaは、最も可能性の高いプログラムに属していない任意の場所に関数の戻り値を作り、(無関係な値でレジスタのほとんどを満たすに加えて)スタックからリターンアドレスを削除します。誤った数の引数が与えられた場合、プログラムは正しく動作するはずです。

BTW:あなたのコードでレジスタのプッシュ(enterによって行われたebpのプッシュ以外)は必要ではありません。

+0

感謝の男!これがうまくいった! – user7275873

関連する問題