Ben*_* I. 1 syntax assembly 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
Run Code Online (Sandbox Code Playgroud)
我只想从那里迈出一步,打印ascii字符52(即"4").到目前为止,这是我最好的尝试:
include c:\masm32\include\masm32rt.inc
.data
.code
start:
myvar db 52
invoke StdOut, myvar
inkey
invoke ExitProcess, 0
end start
Run Code Online (Sandbox Code Playgroud)
它无故障地组装和链接,但是当我运行它时会崩溃.我知道它最后没有0个字符,但是invoke StdOut, myvar,0StdOut的参数太多了.
我最终的目标是能够打印多位数字,如Alexey Frunze所述:
x86 assembly(masm32) - 如何将多位数据拆分为单个字符
但是由于我在语法方面遇到了很多麻烦,我正在采取措施.我找到了这个,但它没有解释如何在语法上添加48部分:
x86程序集 - 如何显示整数2,而不是第二个ASCII字符
请帮我翻过这些开场障碍,谢谢!
首先,myvar db 52是在错误的地方.程序启动时,计算机db 52会将其视为指令.其次,0值(不要说字符)不是参数,StdOut必须在数据的末尾.StdOut需要作为参数指向以零结尾的字符串的指针.你不能给它一个直接的值,函数会把它作为指针.顺便说一句:考虑这StdOut是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
Run Code Online (Sandbox Code Playgroud)
在使用'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
Run Code Online (Sandbox Code Playgroud)
另外看看这里.