2017-12-21 14 views
0

ユーザから入力を得るためにmacroを書きました。入力をいくつかのレジスタに保存する必要があります。
gdbは、保存された値が入力と異なることを私に示しています!ここに私のコードです:
アセンブリ - 割り込みを入力してレジスタに保存する方法

%macro exit 0 
    mov eax, 1 
    int 0x80 
%endmacro 


%macro get_input 0   ; input is a number 
push_all_general_purpose_regs 
    push_all_general_purpose_regs 
    mov eax, 3    ; system call number --> sys_read 
    mov ebx, 2    ; file descriptor 
    mov ecx, num    
    mov edx, 4 
    int 0x80 
    sub dword [num], '0'  ; convert character to number : forexample '3'->3 
    POP_all_general_purpose_regs 
%endmacro 


%macro push_all_general_purpose_regs 0 
    push eax 
    push ebx 
    push ecx 
    push edx 
%endmacro 


%macro POP_all_general_purpose_regs 0 
    POP edx 
    POP ecx 
    POP ebx 
    POP eax 
%endmacro 

section .bss 
    num resb 4 ; num is where input will be stored at 

section .text 
global _start 
_start: 

    get_input 
    lea ecx, [num] ; now ecx holds the address of input 
    mov ebx, [ecx] ; I want to move input to ebx 
    finished: 
    exit 

、ここgdbの出力です:

(gdb) break finished 
Breakpoint 1 at 0x80480ad 
(gdb) run 
Starting program: /assembly-project/main_project/test_project /sta/a.out 
67 

Breakpoint 1, 0x080480ad in finished() 
(gdb) info registers 
eax   0x0  0 
ecx   0x80490b4  134516916 
edx   0x0  0 
ebx   0xa3706 669446 
esp   0xffffd390  0xffffd390 
ebp   0x0  0x0 
esi   0x0  0 
edi   0x0  0 
eip   0x80480ad  0x80480ad <finished> 
eflags   0x206 [ PF IF ] 
cs    0x23  35 
ss    0x2b  43 
ds    0x2b  43 
es    0x2b  43 
fs    0x0  0 
gs    0x0  0 
(gdb) 

見られるように、私の入力は67ですがebxの値は669446

+2

。また1バイトになりますが、4をロードします。 '6'は' bl'で見つけることができます。 – Jester

+0

ちょっと意見...なぜそれらのマクロを紹介しますか?彼らはデバッグ/レビューのためにあなたのソースを悪夢に変えます。これは通常、アセンブリの開発時間の60〜90%です。あなたの目的がタイピングに時間を節約することであるならば、それを忘れてください、それは総開発時間のわずかな量です、ソースを読んで、あなたが最も長い時間を節約できる場所であることを理解してください。マクロは、その中のすべての命令を覚えておくか、ソース内を上書きして再読み込みする必要があるため、特にパラメータ化またはネストされた読み込みが難しいです。しばしば簡単な 'call procedure'はあなたの入力を救うのに十分です。 – Ped7g

+0

@Jesterあなたは正しいです、私はそれに気付かなかった。 –

答えて

1

669446 = 0xA3706ですそれはあなたの3文字の入力です、私はあなたを見せてください。

元の入力は、36 37 0A(3文字は'6', '7', '\n')の3バイトとして読み込まれます。

.bssセクションがバイナリロード+初期化時にLinux OSによってゼロにされるため、.bssの4番目のバイトはゼロです。

I.e.アドレスnumのメモリにはに等しい値dwordが含まれています。

次に、あなたがsub dword [num], '0'によるものから0x00000030を引くので、あなたが得たまさに、結果は値0x000A3706です...それは10進数で669446です。

あなたが書いたとおり、すべてが正確に正しく動作します。

sys_readサービスと入力多桁の10進整数に、あなたは次のように、ループ内で、文字によって彼らに文字を解析する必要があります:あなたのコードは唯一の1桁の数を可能

result = 0 
for (digit : input_string) { // from first to last input character 
    if (!is_valid_digit(digit)) break; // will catch '\n', or other invalid char 
    result *= 10; 
    result += digit - '0'; 
} 
// here "result" is binary integer value equal to the decimal encoded in string. 
関連する問題