나는 꽤 간단한 프로젝트로 생각합니다. 사용자에게 0-255 사이의 숫자와 2-9 사이의 숫자를 물어보십시오. 그리고 그 기지에서 출력. 간단히 일반적인 분할 알고리즘을 수행하고 나머지를 가져온 다음 스택으로 밀어 넣고 다시 팝 오프하여 역순으로 사용자에게 출력 할 계획입니다. 그러나 몇 인쇄 디버깅 문을 삽입 한 후 나는 나머지NASM 어셈블리 번호를 기본 변환
; Run using nasm -f elf -g -F stabs proj4.asm ; gcc -o proj4 proj4.o -m32 ; To execute type proj4
%macro SAVE_REGS 0 push eax push ecx push edx %endmacro
%macro RESTORE_REGS 0 pop edx pop ecx pop eax %endmacro
%macro CALL_PUTS 1 push %1 call puts add esp, 4 %endmacro
%macro CALL_SCANF 2 push %1 push %2 call scanf add esp, 8 %endmacro
%macro CALL_PRINTF1 1 push %1 ;The address of the string to print call printf add esp, 4 %endmacro
%macro CALL_PRINTF2 2 push %1 ;The formatted string with a %char place holder push %2 ;The item to place into the place holder call printf add esp, 8 %endmacro
SECTION .data
prmptNumMsg: db "Enter a number between 0 and 255: ", 0 prmptBaseMsg: db "Enter a base between 2 and 9: ", 0 remShow: db 'The the remainder is: %d', 10, 0 numShow: db 'The number is %d', 10, 0 baseShow: db 'The base is %d', 10, 0 printed: db 'Looped in division method', 10, 0 poped: db 'Looped in pop method',10, 0 ansShow: db '8d', 10, 0
numFormat db '%d', 0 stringFormat db '%s', 0 SECTION .bss numVal resd 1 baseVal resd 1 ans resd 9 i resd 1 n resd 1 j resd 1
SECTION .text global main
매우 이상한 결과를 얻고있다 4,138,801,793,210 main:
push ebp ; Set up stack frame for debugger mov ebp, esp push ebx push esi push edi ;Everything before this is boilerplate
getInt: CALL_PRINTF1 prmptNumMsg
;push numVal ;push numFormat ;call scanf ;add esp, 8 CALL_SCANF numVal, numFormat
mov eax, dword[numVal] mov ebx, dword 0 ;check below 0 cmp eax, ebx jb getInt mov eax, dword[numVal] mov ebx, dword 255 ;check above 255 cmp eax , ebx ja getInt ;VALID INTEGER PAST THIS POINT
getBase: CALL_PRINTF1 prmptBaseMsg
CALL_SCANF baseVal, numFormat mov eax, dword[baseVal] mov ebx, dword 0 cmp eax, ebx jb getBase mov eax, dword[baseVal] mov ebx, dword 9 cmp eax, ebx ja getBase
;END GETBASE ;VALID BASE NUMBER PAST THIS POINT mov eax, dword[numVal] mov [n], eax ;set n to the current number value CALL_PRINTF2 eax, numShow mov eax, dword 0 mov [i], eax mov eax, dword[baseVal] CALL_PRINTF2 eax, baseShow doDivision: ;CALL_PRINTF1 printed xor edx, edx mov eax, dword[n] mov ebx, dword[baseVal] div ebx ;edx = remainder eax = quotient mov [n], eax ;save quotient
CALL_PRINTF2 eax, numShow CALL_PRINTF2 edx, remShow
;push edx ;save remainder on stack to pop in reverse order later ;mov [n], eax ;move quotient to eax
mov ebx, dword[i] inc ebx mov [i], ebx ;i++
;mov eax, [i] mov ecx, dword 8 cmp ebx, ecx jb doDivision ;END DO DIVISION
end:
Enter a number between 0 and 255: 105 Enter a base between 2 and 9: 4 The number is 105 The base is 4 The number is 26 The the remainder is: 13144896 The number is 6 The the remainder is: 13144896 The number is 1 The the remainder is: 13144896 The number is 0 The the remainder is: 13144896 The number is 0 The the remainder is: 13144896 The number is 0 The the remainder is: 13144896 The number is 0 The the remainder is: 13144896 The number is 0 The the remainder is: 13144896
내가 루프 올 8 번을 원하는 다음과 같이 프로그램 내 출력을 실행 ;Everything after this is boilerplate pop edi pop esi pop ebx mov esp, ebp pop ebp ret
는
, 각 사업부 작업의 몫 그러나 내가하는 것 나머지 미친 번호를 얻고, 올바른입니다 edx에서 개최됩니다. 나는이 원인을 이해하지 못한다.
이 두 줄의 순서를 변경하고 어떤 일이 발생하는지 확인하십시오. 그런 다음 이유를 알아보십시오. 'CALL_PRINTF2 eax, numShow'와'CALL_PRINTF2 edx, remShow'를 나눕니다. –
무엇? ** 당신은 당신이 그것을 인쇄하기 전에 나머지를 계산해야한다는 것을 의미합니까? ** 누구든지 그런 말도 안 들었습니다. 초기화되지 않은 값을 먼저 인쇄 한 다음 시도하고 계산하십시오 ... 무언가 ... 좋은 캐치, 약간의 설명이있는 답 형식으로 작성하고 OP는 받아 들여야합니다. –
추가 힌트 :'printf'는 값을 반환합니다. 그것을 어디에 넣을 까? 덧붙여 말하자면 문제는 [매우 친숙하다] (http://stackoverflow.com/questions/26657061/nasm-program-assembly-language/26686793#26686793) (질문하는 것이 더 구체적 임에도 불구하고). – Tony