2017-12-21 8 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를로드합니다. 'bl'에서'6 '을 찾을 수 있습니다. – Jester

+0

그냥 의견 ... 왜 그 매크로를 소개합니까? 그들은 디버깅/검토를 위해 소스를 근사한 악몽으로 바꿀 것인데, 이는 어셈블리에서 개발 시간의 60-90 %입니다. 귀하의 목적이 타이핑에 시간을 절약하는 것이라면, 그것을 잊어 버리십시오, 그것은 전체 개발 시간의 작은 양입니다. 소스를 읽고 그것을 이해하면 가장 많은 시간을 절약 할 수 있습니다. 매크로는 모든 명령어를 기억해야하거나 소스에서 위/아래로 이동하여 다시 읽어야하기 때문에 특히 매개 변수화되거나 중첩 된 매크로를 읽기가 어렵습니다. 종종 간단한 '호출 절차'만으로도 타이핑을 저장할 수 있습니다. – Ped7g

+0

@Jester 당신 말이 맞아, 나는 그것을 알아 차리지 못했다. –

답변

1

669446 = 0xA3706 인 그리고 그것이 당신의 3 자 입력입니다, 제가 보여 드리겠습니다.

원래 입력은 36 37 0A (3 자 '6', '7', '\n')의 3 바이트로 읽습니다.

.bss 섹션이 바이너리 로딩 + 초기화 중에 Linux OS에 의해 제로화되므로 .bss의 네 번째 바이트는 0입니다.

e.e. num 주소의 메모리는 과 동일한 값인 dword을 포함합니다.

은 그럼 당신은 sub dword [num], '0'에 의해 그에서 0x00000030을 빼기 때문에 결과 값 0x000A3706 ... 그리고 그건 당신이있어 정확하게, 진수 669446입니다.

모든 것이 정확하게 작성되었습니다. 작성한대로 정확하게 작동합니다. sys_read 서비스를 입력 여러 자리의 십진수 정수로

, 당신처럼, 루프에서, 문자로 그들에게 문자를 구문 분석해야합니다 :

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. 
관련 문제