Assembly 不知道如何在MASM32中打印数字
我讨厌问这样的基本问题。这让我看起来像是在偷懒!但我花了几个小时查看文档,无论出于什么原因,我都无法在这个小问题上保持清醒的头脑 我想在屏幕上打印字符4。我可以将其作为字符串来执行,但不能从ascii值执行 以下是工作代码:Assembly 不知道如何在MASM32中打印数字,assembly,syntax,masm32,Assembly,Syntax,Masm32,我讨厌问这样的基本问题。这让我看起来像是在偷懒!但我花了几个小时查看文档,无论出于什么原因,我都无法在这个小问题上保持清醒的头脑 我想在屏幕上打印字符4。我可以将其作为字符串来执行,但不能从ascii值执行 以下是工作代码: include c:\masm32\include\masm32rt.inc .data num4 db "4", 10,0 .code start: invoke StdOut, addr num4 inkey invoke ExitPro
include c:\masm32\include\masm32rt.inc
.data
num4 db "4", 10,0
.code
start:
invoke StdOut, addr num4
inkey
invoke ExitProcess, 0
end start
我只是想从那里迈出一小步,打印ascii字符52,也就是4。以下是我迄今为止最好的尝试:
include c:\masm32\include\masm32rt.inc
.data
.code
start:
myvar db 52
invoke StdOut, myvar
inkey
invoke ExitProcess, 0
end start
它组装和链接没有问题,但当我运行它时崩溃了。我知道它的结尾没有0字符,但是调用StdOut,myvar,0有太多的StdOut参数
我的最终目标是能够打印一个多位数的数字,如Alexey Frunze所述:
但是,由于我在语法方面遇到了很多麻烦,我正在采取一些小步骤。我发现了这个,但它没有解释如何在语法上添加48部分:
请帮我克服这些障碍,谢谢 首先,myvar db 52位于错误的位置。当程序启动时,计算机来到db 52并将其视为一条指令。其次,0值不表示字符不是StdOut的参数,必须位于数据的末尾。StdOut需要一个指向以零结尾的字符串的指针作为参数。您不能给它一个直接值,但函数会将其作为指针。BTW:考虑STDUT是MasM32的函数,而不是Windows内核的函数。您的程序应该如下所示:
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:assembly将整数转换成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
另外请看一看。首先,myvar db 52位于错误的位置。当程序启动时,计算机来到db 52并将其视为一条指令。其次,0值不表示字符不是StdOut的参数,必须位于数据的末尾。StdOut需要一个指向以零结尾的字符串的指针作为参数。您不能给它一个直接值,但函数会将其作为指针。BTW:考虑STDUT是MasM32的函数,而不是Windows内核的函数。您的程序应该如下所示:
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:assembly将整数转换成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
也请看一看。这个答案令人惊讶,并为我未来的目标提供了指导,尽管我还不了解这个答案的每个方面,但您的评论非常有用,我认为这将随着时间和毅力而来。但是你对我介绍的非工作代码也有答案吗?哦,还有,你为什么要声明clrf?它似乎没有在其他任何地方使用。@Choirbean:请查看更新的答案。我已经尽力了:-非常感谢你,rkhb。我希望我可以在场外与您联系,询问其他问题-您非常清楚。这太不可思议了!这个答案令人惊讶,并为我未来的目标提供了一个指导,尽管我还不完全理解这个答案的每一个方面,但是你的评论非常有用,我认为这将随着时间和坚持而来。但是你对我介绍的非工作代码也有答案吗?哦,还有,你为什么要声明clrf?它似乎没有在其他任何地方使用。@Choirbean:请查看更新的答案。我已经尽力了:-非常感谢你,rkhb。我希望我可以在场外与您联系,询问其他问题-您非常清楚。这太不可思议了!