2017-01-10 13 views
0

키보드에서 배열까지 10 개의 숫자를 읽은 다음 쓰는 것이 큰 문제가 있습니다.NASM x64 배열을 읽고 번호를 쓰십시오.

mov rcx, arr + qword [n]*8 - 실제로 오류가 발생하기 때문에 올바르게 수정하는 방법을 모르겠습니다. 또한 다음과 같이 숫자를 읽으려는 경우 mov rdx, 1을 어떻게 설정해야합니까? 12 123 1234 숫자뿐 아니라?

나는 모든 종류의 도움에 감사 할 것입니다.

global main 

section .text 

main: 
mov rbp, rsp; for correct debugging 
mov rdi, 0 
_in: 


mov rax, 3 
mov rbx, 0 
mov rcx, arr + rdi*8 
mov rdx, 1 
int 80h 


mov rax, 3 
mov rbx, 0 
mov rcx, blank 
mov rdx, 1 
int 80h 

inc qword [n] 
cmp qword [n], 10 
jz _next 
jmp _in 
inc rdi 

_next: 
mov qword [n], 0 
mov rdi, 0 
_out: 
mov rax, 4 
mov rbx, 1 
mov rcx, arr + rdi*8 
mov rdx, 1 
int 80h 

mov rax, 4 
mov rbx, 1 
mov rcx, nl 
mov rdx, 1 
int 80h 

inc qword [n] 
cmp qword [n], 10 
jz _end 
jmp _out 
inc rdi 
_end: 

mov rax, 1 
mov rbx, 0 
ret 

section .data 

arr times 10 dq 0 
blank db 0 
n dq 0 
nl db 10 
+0

색인을 생성하려면 'n'을 레지스터에로드해야합니다. 귀하의 질문의 나머지 부분은 명확하지 않습니다. – Jester

+0

불투명하지만 미안하지만 영어가 모국어가 아닙니다. 나는 mov rdx를 수정할 때 2를 의미합니다. 11과 같은 키보드에서 숫자를 읽을 수 있습니다. mov rdx를 수정할 때 3, 111과 같은 숫자를 읽을 수 있습니다. 모든 가능한 길이의 길이를 읽고 싶습니다. –

+0

숫자로 루프 숫자로 읽으시겠습니까? – Jester

답변

0

입력 및 데이터 구조에 관하여.

루프 당 숯불 (rdx=1)을 계속 읽으십시오. 입력 문자는 예를 들어 '1', '2', '3', '4', '5', 10이고, 문자 10은 새 라인입니다 (13, 9, 32 같은 다른 공백 문자도 확인하거나 테스트 플립, '0'..'9' 범위 밖의 문자는 숫자 끝임).

숫자를 읽는 동안 숫자를 문자열로 저장할 것인지 또는 숫자로 저장할 것인지 결정하십시오.

문자열 인 경우 arr + n * 8 + input_char_index 주소의 메모리에 모든 새 숫자를 씁니다. 번호 뒤에 터미네이터로 0 값을 넣을 수 있습니다 (현재 배열에는 최대 7 자의 긴 문자열 + 각 " n ") 또는 문자열 길이를 별도의 배열 또는 요소의 첫 번째 바이트로 저장하고 첫 번째 문자를 길이 바이트 뒤에 +1 오프셋으로 이동합니다 (원하는대로 데이터 구조를 디자인 할 수 있음). 그러한 문자열을 표시하려면 주소 lea rcx,[arr+n*8]을로드하고 길이를 strlen으로 계산하십시오 (0이 발견 될 때까지 char로 + counts char을 읽습니다). 또는 어딘가에 저장하면 길이를로드하고 sys_write.

당신이 번호를 저장하려면

, 모든 자리 읽기 후, (예를 rdi에 대한) 입력의 제로 앞서 일부 여분의 레지스터를 설정 할 add rdi,rdi lea rdi,[rdi+rdi*4] => 즉, 다음 (64B) 0 ASCII 숫자의 입력 문자 변환 rdi *= 10입니다 -9 값을 입력하고 rdi ... 비 숫자 또는 개행 문자가 읽힐 때까지 루프를 추가합니다 (단, 부호가없는 숫자는 19 자리 숫자가 입력 될 때 64 비트 부호로 오버 플로우됩니다). 입력이 끝나면 arr에 값을 저장합니다. 이제 arr에 숫자 QWORD 값이 포함됩니다.

출력하려면 숫자 값에서 일부 메모리 버퍼로 반대 방향으로 변환해야하며 숫자 ASCII 문자로 생성해야합니다 (버퍼가 충분히 크고 다시 20+ 문자는 64b 값으로 안전합니다). 숫자를 ASCII 문자열로 메모리에 저장하고 길이를 알고 있으면 SYS_WRITE로 stdout 할 수 있습니다.

자주 튜토리얼을 따르고 공통 데이터 구조/etc, 메모리, 문자열 인코딩, 레지스터, x86 주소 지정 모드 등에 대한 몇 가지 이론을 다시 읽는 것이 좋습니다. 직접 코드를 작성하기 전에 네가 너무 많이 추측하고있는 것, 일들이 어떻게 작용하는지).

+0

대단히 고마워, 너는 나를 더 잘 이해하는 데 많은 도움을 주었다. 이제는 내 프로그램이 완벽하게 작동합니다. –