Как преобразовать DWORD в базу данных

Я хочу отобразить счет в игре, которую я создал в MASM32, и у меня есть проблема, как мне преобразовать DWORD в DB (строку).

Существует функция crt__itoa для преобразования dword в целое число, но по какой-то причине она не работает (мне нужно включить другую lib?).

Существует функция TextOutA для отображения оценки, но снова я не могу ее распечатать, потому что у меня нет строки, чтобы она могла ее распечатать.

Ответы

Ответ 1

Мне нужно включить другой lib? - Вероятно. Вам нужно msvcrt.inc и msvcrt.lib для crt__itoa.

masm32rt.inc - это швейцарский армейский нож для таких случаев. Вот рабочий пример:

include c:\masm32\include\masm32rt.inc

.DATA
    fmt db "%s",10,0
    num dd 1234567
    num_str db 16 dup (?)

.CODE
main PROC

    ; with CALL:

    push 10
    push OFFSET num_str
    push num
    call crt__itoa
    add esp, 12

    push OFFSET num_str
    push OFFSET fmt
    call crt_printf
    add esp, 8

    ; or with INVOKE:

    invoke crt__itoa, num, OFFSET num_str, 10
    invoke crt_printf, OFFSET fmt, OFFSET num_str

    invoke ExitProcess, 0

main ENDP

END main

Программа не останавливается. Если вы не вызываете его в дополнительном окне командной строки, он откроет окно и сразу же закроет его. В Qeditor предлагаю вставить строку "Запуск и пауза" в menus.ini:

...
&Run Program,"{b}.exe"
Run && Pause,cmd.exe /C"{b}.exe" & pause
...

Теперь у вас есть новый элемент в разделе "Проект".

Ответ 2

Далее приведен метод, созданный с Visual Studio 2010 С++, который вручную преобразует EAX в строку (ему не нужна никакая библиотека, просто скопируйте-вставьте и используйте). Он принимает число как параметр, назначает его EAX, преобразует его в строку и выводит строку:

void number2string ( int value ) {
char buf[11];
__asm { ;EXTRACT DIGITS ONE BY ONE AND PUSH THEM INTO STACK.
          mov  eax, value
          mov  ebx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
          mov  cx, 0   ;COUNTER FOR EXTRACTED DIGITS.
        cycle1:       
          mov  edx, 0  ;NECESSARY TO DIVIDE BY EBX.
          div  ebx     ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER.
          push dx      ;PRESERVE DIGIT EXTRACTED (DL) FOR LATER.
          inc  cx      ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
          cmp  eax, 0  ;IF NUMBER IS
          jne  cycle1  ;NOT ZERO, LOOP. 

        ;NOW RETRIEVE PUSHED DIGITS IN REVERSE ORDER.
          mov  esi, 0   ;POINTER TO STRING CHARACTERS.
        cycle2:  
          pop  dx       ;GET A DIGIT.
          add  dl, 48   ;CONVERT DIGIT TO CHARACTER.
          mov  buf[ esi ], dl
          inc  esi      ;NEXT POSITION IN STRING.
          loop cycle2  
          mov  buf[ esi ], 0  ;MAKE IT ASCIIZ STRING.
     }
printf( buf );
scanf( "%s",buf ); // TO STOP PROGRAM AND LET US SEE RESULT.
}

Обратите внимание: предыдущий метод является "void", поэтому вы называете его обычным:

number2string( 1234567890 ); // CONVERT THIS BIG NUMBER IN STRING AND DISPLAY.

Вы можете изменить метод, чтобы вернуть строку или сделать что угодно.

Теперь (для тех, кто достаточно жестким) та же самая предыдущая процедура для чистого ассемблера, сделанная с помощью GUI Turbo Assembler x64 (http://sourceforge.net/projects/guitasm8086/), эта полная программа показывает, как это работает:

.model small

.586

.stack 100h

.data

buf db 11 dup (?) ;STRING.

.code          
start:
;INITIALIZE DATA SEGMENT.
  mov  ax, @data
  mov  ds, ax

;CONVERT EAX TO STRING.
  call dollars        ;FILL BUF WITH '$', NECESSARY TO DISPLAY.
  mov  eax, 1234567890
  call number2string  ;PARAMETER:EAX. RETURN:VARIABLE BUF.

;DISPLAY BUF (EAX CONVERTED TO STRING).
  mov  ah, 9
  mov  dx, offset buf
  int  21h    

;WAIT UNTIL USER PRESS ANY KEY.
  mov  ah, 7
  int  21h

;FINISH PROGRAM.
  mov  ax, 4c00h
  int  21h           

;------------------------------------------
;NUMBER TO CONVERT MUST ENTER IN EAX.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (BUF).

number2string proc
  mov  ebx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
  mov  cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:       
  mov  edx, 0 ;NECESSARY TO DIVIDE BY EBX.
  div  ebx ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER.
  push dx ;PRESERVE DIGIT EXTRACTED (DL) FOR LATER.
  inc  cx  ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
  cmp  eax, 0  ;IF NUMBER IS
  jne  cycle1  ;NOT ZERO, LOOP. 
;NOW RETRIEVE PUSHED DIGITS.
  mov  si, offset buf
cycle2:  
  pop  dx        
  add  dl, 48 ;CONVERT DIGIT TO CHARACTER.
  mov  [ si ], dl
  inc  si
  loop cycle2  

  ret
number2string endp  

;------------------------------------------
;FILLS VARIABLE BUF WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THE STRING WILL BE DISPLAYED.

dollars proc
  mov  si, offset buf
  mov  cx, 11
six_dollars:      
  mov  bl, '$'
  mov  [ si ], bl
  inc  si
  loop six_dollars

  ret
dollars endp  

end start