2015-02-05 8 views
1

나는 그런 기본적인 질문을하는 것이 싫다. 그것은 내가 게으른 것처럼 보이게합니다! 그러나 나는 문서를보고 몇 시간을 보냈습니다. 그리고 어떤 이유에서이 작은 지점에서 머리를 똑바로 돌릴 수는 없습니다.MASM32에서 숫자를 인쇄하는 방법을 알아낼 수 없습니다.

"4"문자를 화면에 인쇄하려고합니다. 문자열로 할 수는 있지만 ascii 값으로는 할 수 없습니다.

include c:\masm32\include\masm32rt.inc 
.data 
    num4 db "4", 10,0 
.code 
start: 
    invoke StdOut, addr num4 
    inkey 
    invoke ExitProcess, 0 
end start 

난 그냥 ("4"입니다)가 인쇄 ASCII 문자 (52)로부터 아기 조치를 취할 원 : 여기

는 작업 코드입니다. 그런 다음 조립 및 문제없이 링크,하지만

include c:\masm32\include\masm32rt.inc 
.data 
.code 
start: 
    myvar db 52 
    invoke StdOut, myvar 
    inkey 
    invoke ExitProcess, 0 
end start 

내가 그것을 실행할 때 충돌 : 여기에 지금까지 최선의 시도이다. 나는 끝에 0 문자가 없다는 것을 알고 있지만 invoke StdOut, myvar,0에는 StdOut에 대한 인수가 너무 많습니다.

x86 assembly (masm32) - how to split multi-digit data into individual characters

내가 구문 너무 많은 문제가 발생하고 있기 때문에, 나는이 복용하고 아기 단계 : 여기 알렉세이 Frunze에 의해 설명 된 바와 같이

내 최종 목표는 여러 자리 숫자를 인쇄 할 수있다 . 나는이 발견,하지만 구문 추가 (48) 부분을 수행하는 방법을 설명하지 않습니다

x86 assembly - how to show the integer 2, not the second ASCII character

날이 개방 장애물 과거를 얻을 수 있도록, 당신을 감사하십시오!

답변

5

먼저 myvar db 52이 잘못된 위치에 있습니다. 프로그램이 시작될 때, 컴퓨터는 db 52에오고 그것을 명령으로 간주합니다. 둘째, 0 값 (문자를 말하지 않음)은 StdOut의 인수가 아니며 데이터의 끝 부분에 있어야합니다. StdOut포인터 인을 0으로 끝나는 문자열에 인수로 사용해야합니다. 직접 값을 줄 수는 없지만 함수는이를 포인터로 사용합니다. BTW : StdOut은 Windows 커널의 기능이 아니라 MASM32의 기능이라고 생각하십시오. 프로그램은 다음과 같아야합니다 :

include c:\masm32\include\masm32rt.inc 
.data 
    myvar db 52, 0 
.code 
start: 
    invoke StdOut, ADDR myvar 
    inkey 
    invoke ExitProcess, 0 
end start 

'StdOut'을 사용하여 출력하기 전에 먼저 문자열을 작성해야합니다. 문자열이지만 숫자가없는 경우 문자열로 변환해야합니다 (Google의 키워드 : "ascii에서 정수로 어셈블리 변환"). 트릭은 숫자를 10으로 반복하여 나누어 나머지를 저장하는 것입니다. 또 다른 트릭은 MASM32 매크로를 사용하는 것입니다.

INCLUDELIB C:\masm32\lib\masm32.lib 
INCLUDE C:\masm32\include\masm32rt.inc 

.DATA 
    decimalstr db 16 DUP (0) 
    myvar db 52 

.CODE 

start PROC 

    movzx eax, myvar   ; Load an 8-bit-byte into a 32-bit-register 
    lea edi, decimalstr  ; Load the address of decimalstr 
    call EAX_to_DEC 
    invoke StdOut, addr decimalstr 

    movzx eax, myvar 
    printf ("\nAnd the lazy MASM32 way: %u\n",eax) 

    invoke ExitProcess, 0 
start ENDP 

EAX_to_DEC PROC    ; ARG: EDI pointer to string buffer 
    mov ebx, 10    ; Divisor = 10 
    xor ecx, ecx   ; ECX=0 (digit counter) 
    @@:      ; First Loop: store the remainders 
    xor edx, edx 
    div ebx     ; EDX:EAX/EBX = EAX remainder EDX 
    push dx     ; push the digit in DL (LIFO) 
    add cl,1    ; = inc cl (digit counter) 
    or eax, eax   ; AX == 0? 
    jnz @B     ; no: once more (jump to the first @@ above) 
    @@:      ; Second loop: load the remainders in reversed order 
    pop ax     ; get back pushed digits 
    or al, 00110000b  ; to ASCII 
    stosb     ; Store AL to [EDI] (EDI is a pointer to a buffer) 
    loop @B     ; until there are no digits left 
    mov byte ptr [edi], 0 ; ASCIIZ terminator (0) 
    ret      ; RET: EDI pointer to ASCIIZ-string 
EAX_to_DEC ENDP 

END start 

here도 참조하십시오.

+0

이 답변은 놀라운 것이며 내 미래 목표에 대한 지침을 제공합니다 (아직이 답변의 모든 측면을 이해하지 못했지만 귀하의 의견은 매우 유용하며 시간과 끈기와 함께 올 것이라고 생각합니다) . 하지만 내가 제시 한 비 작동 코드에 대한 대답도 있습니까? –

+0

아, 그리고 왜 당신은 clrf를 선언 했습니까? 다른 곳에서는 사용되지 않습니다. –

+0

@Choirbean : 업데이트 된 답변을 살펴보십시오. 나는 최선을 다했다 :-) – rkhb

관련 문제