2016-10-13 5 views
0

저는 Linux VM에서 NASM과 함께 x86 어셈블리 코드, 인텔 형식을 사용하고 있습니다. 프로그램은 두 자리를 공백으로 구분하여 합계를 출력합니다. 나는 GDB로 그것을 보았고 결과를 인쇄하기를 거꾸로 거부한다는 점을 제외하고는 모든 일을 오류없이 끝내도 괜찮습니다. 나는 어셈블리 코드를 처음 사용하기 때문에 여기서 잘못하고있는 실마리가 없다.어셈블리 프로그램 누락 출력

EDIT : 관련성이 더 높은 비트 만 포함하도록 코드를 단축했습니다. 나는 생각한다. 지금 당장 볼

;Variables 
section .bss 
    digit  resb 1   

_start: 
    ;Input Prompt 
     ;Code block edited out. 

    ;Reads 1st digit input, checks if the read operation was successfull, 
    ;and stores the value in EAX. 
    call _readDigit 
    cmp edx,0 
    jne _end 
    mov eax,ecx 

    ;Reads 2nd digit input, checks for read success, 
    ;and stores the value in EBX. 
    call _readDigit 
    cmp edx,0 
    jne _end 
    mov ebx,ecx 

    ;Sums EAX and EBX, stores result in ECX, 
    ;and calls the write procedure. 
    call _newLine 
    add eax,ebx 
    mov ecx,eax 
    call _writeSum  

;Prints out the sum of two digits in the format 0X for values 
;below 10, or 1X for values greater than 9. 
_writeSum: 
    push eax 
    push ebx 
    push ecx 
    push edx 

    mov [digit],ecx 
    cmp ecx,9  ;Checks if sum > 9. 
    jg _twoDigits 

;Prints out 0 for the first digit in the result. 
_oneDigit: 
    mov ecx,48 
    mov edx,1 
    mov ebx,STDOUT 
    mov eax,SYS_WRITE 
    int 80h 

    mov ecx,[digit] 
    jmp _lastDigit 

;Prints out 1 for the first digit in the result, 
;and subtracts 10 from ECX. 
_twoDigits: 
    mov ecx,49 
    mov edx,1 
    mov ebx,STDOUT 
    mov eax,SYS_WRITE 
    int 80h 

    mov ecx,[digit] 
    sub ecx,10 

;Converts ECX to ASCII and prints this as the 
;second digit in the result. 
_lastDigit: 
    add ecx,'0' 
    mov [digit],ecx 

    mov ecx,[digit] 
    mov edx,1 
    mov ebx,STDOUT 
    mov eax,SYS_WRITE 
    int 80h 

    pop edx 
    pop ecx 
    pop ebx 
    pop eax 
    ret 
+0

strace ('strace./a.out')로 코드를 실행하여 실제로 시스템 호출로 전달되는 인수를 확인하십시오. BTW, 당신의 코드는 꽤 오랫동안 의문입니다. [mcve]의 최소 부분을 만족 시키지는 못합니다. 참고 자료 : [x86 태그 wiki] (http://stackoverflow.com/tags/x86/info) 많은 좋은 것들. –

+1

처음에는'digit resb 1'이 무슨 일을하는지,'mov ecx, [digit]'는 무엇을하는지 설명해보십시오 (잘못된 조합입니다). 그러나 그 부분은 우연히 작동 할 수 있습니다 (행운을 피하기 위해 코드 시작 부분에'mov [digit], dword 0xDEADBEEF'를 수행하십시오). 그런 다음'SYS_WRITE'를 사용하는 방법을 살펴보십시오. msg를 표시하면 작동합니다. 합계를 표시하려면 다른 방식으로 사용하십시오 (그런 식으로는 작동하지 않습니다). 이 'int 80h'호출의 인수를 자세히 살펴보십시오. – Ped7g

답변

0

한 것은 당신이 직접 ECX로 ([숫자], 48, 49)는 인쇄 원하는 값을 이동하는 것입니다. SYS_WRITE는 ecx가 값이 아닌 텍스트 문자열에 대한 POINTER를 포함 할 것으로 기대합니다.

두 번째로 문자열 (실제로는 모든 입력)에 예상 값을 수동으로 채우는 것이 좋습니다. 그러면 문제가 읽기와 같은 것이 아닌지 확신 할 수 있습니다. 코드라는 코드를 생략하면 ' 최소한의 오류 케이스로 당신을 데려 오지만, 단지 대부분의 경우에 해당되는 가정을합니다.