我想在我在MASM32中构建的游戏中显示分数,我有一个问题,如何将DWORD转换为DB(字符串)。
有一个函数crt__itoa
将dword转换为整数,但由于某种原因它不起作用(我是否需要包含其他lib?)。
有一个功能TextOutA来显示分数,但我再次打印出来因为我没有字符串所以它可以打印出来。
答案 0 :(得分: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
...
现在,您在“项目”下有一个新项目。
答案 1 :(得分:1)
接下来是使用Visual Studio 2010 C ++制作的方法,它手动将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'S 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.
}
注意:以前的方法是“无效”,所以你像往常一样调用它:
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