Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 不知道如何在MASM32中打印数字_Assembly_Syntax_Masm32 - Fatal编程技术网

Assembly 不知道如何在MASM32中打印数字

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

我讨厌问这样的基本问题。这让我看起来像是在偷懒!但我花了几个小时查看文档,无论出于什么原因,我都无法在这个小问题上保持清醒的头脑

我想在屏幕上打印字符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
我只是想从那里迈出一小步,打印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。我希望我可以在场外与您联系,询问其他问题-您非常清楚。这太不可思议了!