2017-12-19 48 views
0

내가 사용자와 "안녕하세요, 여기에 이름이"어셈블리에서 사용자 입력을 수락 하시겠습니까? (맥 OS에) 단일 프로그램

이 지금까지 내 코드 인쇄에서 이름을 받아이 간단한 프로그램 몇 가지 문제가 있어요 ...

%define SYSCALL_WRITE 0x2000004 
%define SYSCALL_EXIT 0x2000001 
%define SYSCALL_READ 0x2000003 

SECTION .data 
    prompt db "Enter name " 
    text2 db "Hello, " 

SECTION .bss 
    name resb 16 

SECTION .text 
    global _start 

_start: 
    call _printText1 
    call _getInput 
    call _printText2 
    call _printName 
    mov rax, SYSCALL_EXIT 
    mov rdi, 0 
    syscall 

_printText1: 
    mov rax, SYSCALL_WRITE 
    mov rdi, 1 
    mov rsi, prompt 
    mov rdx, 11 
    syscall 
    ret 

_getInput: 
    mov rax, SYSCALL_READ 
    mov rdi, 0 
    mov rsi, name 
    mov rdx, 1 
    syscall 
    ret 

_printText2: 
    mov rax, SYSCALL_WRITE 
    mov rdi, 1 
    mov rsi, text2 
    mov rdx, 7 
    syscall 
    ret 

_printName: 
    mov rax, SYSCALL_WRITE 
    mov rdi, 1 
    mov rsi, name 
    mov rdx, 16 
    syscall 
    ret 

출력 할 때 "Hello"가 출력되지 않습니다. 다음 명령 행하기 전에 인쇄 입력 한 이름의 첫 글자 ...

nMy-MacBook:Assembly username$ ame

하고 이름의 나머지는 시스템이

-bash: ame: command not found

을 응답하는 명령 인수로 받아 들여진다

내가 뭘 잘못하고 있니? _getInput 및 _printName 함수를 삭제하고 여전히 "Hello"를 인쇄하지 않고 "Enter name"만 인쇄합니다.

감사합니다.

+0

당신이 디버거를 사용하고 있습니까? – InfinitelyManic

+0

@InfinitelyManic 난 그냥 내 맥에서 터미널을 사용하고 있습니다. – srsrso

+0

예 - 실제로 실행중인 어셈블리 코드를 단계별로 실행하기 위해 일부 디버거 소프트웨어를 사용하고 있습니까? 디버거를 사용하면 오류 지점을 식별하는 데 도움이됩니다. 예를 들어 GDB를 사용합니다. 그러나 커맨드 라인에서 Linux OS 나 OpenBSD를 사용합니다. – InfinitelyManic

답변

1

어셈블리에서는 모든 비트를 고려해야합니다. 특히 입력과 출력을 할 때.

다음은 임의의 길이를 선택한 RDX에 대한 수정 사항이있는 부분 코드입니다.

마지막 줄에는 명령 줄 프로그램 실행, 프롬프트, 사용자 입력, 최종 출력이 나와 있습니다.

; reference: 
; https://stackoverflow.com/questions/47889972/accepting-user-input-in-assembly-simple-program-on-macos 

; lsb_release -a 
; Distributor ID: Ubuntu 
; Description: Ubuntu 16.04.3 LTS 
; Release:  16.04 
; Codename:  xenial 

; assemble and link 
; nasm -f elf64 -g -F dwarf srsrso_001.s -o srsrso_001.o && ld srsrso_001.o -o srsrso_001 

;%define SYSCALL_WRITE 0x2000004 
;%define SYSCALL_EXIT 0x2000001 
;%define SYSCALL_READ 0x2000003 

SECTION .data 
    prompt db "Enter name " 
    text2 db "Hello, ",0xa,0 

     SYSCALL_WRITE equ  1 
     SYSCALL_EXIT equ  60 
     SYSCALL_READ equ  0 

SECTION .bss 
    name resb 0xff    ; some length 

SECTION .text 
    global _start 

_start: 
call _printText1 
call _getInput 
call _printText2 
call _printName 

    mov rax, 60 
    mov rdi, 0 
    syscall 

_printText1: 
    mov rax, SYSCALL_WRITE 
    mov rdi, 1 
    mov rsi, prompt 
    mov rdx, 11 
    syscall 
    ret 

_getInput: 
    mov rax, SYSCALL_READ 
    mov rdi, 0 
    mov rsi, name 
    mov rdx, 0xff ; some length 
    syscall 
    ret 

_printText2: 
    mov rax, SYSCALL_WRITE 
    mov rdi, 1 
    mov rsi, text2 
    mov rdx, 7 
    syscall 
    ret 

_printName: 
    mov rax, SYSCALL_WRITE 
    mov rdi, 1 
    mov rsi, name 
    mov rdx, 0xff ; some length 
    syscall 
    ret 

예 출력 :

$ ./srsrso_001 
Enter name David John Lewis Benjamen Kyle Smith-Wenson 
Hello, David John Lewis Benjamen Kyle Smith-Wenson 
+0

예제 입출력을 보여주기 위해 Upvoted하지만 65535 바이트 길이의 입력을 요청했지만 입력 버퍼 크기를 표시하지 않았습니다. 즉원래의'name resb 16 '은 다른 버그이며 16 문자 이상 입력하면 응용 프로그램이 충돌 할 수 있습니다. 당신이 직접 썼던 것처럼 : * "어셈블리에서는 모든 비트를 고려해야합니다."*는 저장 공간을 포함합니다. 고쳐주세요. (종종 빌드 단계를 포함시키는 것도 좋지만, 질문보다는 대답과 비슷하지만, 임의의 독자가 결과를 재현하는 것이 더 쉽습니다.) – Ped7g

+1

+ Peg7g - 내 변경 사항이 도움이 되었기를 바랍니다. 고맙습니다. – InfinitelyManic