【问题标题】:Output REAL 4 value in Assembly在汇编中输出 REAL 4 值
【发布时间】:2017-03-11 20:26:35
【问题描述】:

我正在创建一个包含一些简单除法的汇编程序(intel 8086 masm32)。一切都在工作,直到该部门产生了一个浮动。

因为当您将浮点数加载到 eax 寄存器时,它只会返回一个大数字。

为了尝试解决我发现的有关 FUP 的问题,并使用 REAL 4 来存储浮点数并且它可以工作。
我的问题是如何使用 WriteConsoleA WindowsAPI 将 float REAL 4 值输出到控制台? 或者在这种情况下可能有不同的方法来处理浮动?

提前致谢

【问题讨论】:

  • 您需要自己转换成文本,或者使用 C 库(如果有)。
  • 如果您不需要浮点结果,您可以使用整数除法指令 DIV 和 IDIV,因为整数更容易转换为文本。
  • @Jester 谢谢,C 库不是一个真正的选择,我会尝试将其转换为文本。虽然根据我的理解,这并不像听起来那么容易......

标签: assembly x86 x86-16 masm32


【解决方案1】:

幸运的是,我不久前仅使用基本指令手动编写了一些与十进制例程之间的字符串。

它们已经被我正在帮助的另一个小组注释掉,但您可能也会发现它们很有用。

这都是简单的东西,即“strlen”过程通常可能使用 scasb 等更快,但它们基本上是初学者的教具,但作为 ASM,它们当然可以轻松快速地完成任何涉及到的任务人际交往。可能比 wsprintf 等更快。因为他们只处理一个案例(十进制)。

它们仅用于整数,但是由于您只想输出十进制字符串,因此输出整数部分后跟 02Eh 然后将小数部分乘以 10^SignificantPlaces 并写下应该相当简单也出去了。

玩得开心=D

哦,顺便说一句:对于许多需要精确计算的除法工作,但最终结果最终是整数,那么只要我使用的值不是太大,我觉得它很方便只需 shl xxx,8 或 shl xxx,16 一切,然后是 div 和其他任何东西,直到我得到结果,然后只是 shr xxx,不管一切,继续卡车运输;)

可能不适合您当前的项目,但通常是一种有用的方法。

.data?
  decbuf db 32 dup(?)

.code

;  DECIMAL to/from STRING routines
;        Lambchops 2/2017
;       ( a boy from AUS )


strlen proc saddr:DWORD ; 
; return length of string at saddr
  mov eax,saddr
  dec eax
  @@:
    inc eax
    cmp byte ptr [eax], 0
    jnz @B
  sub eax,saddr
  ret
strlen endp

mul10 proc val:DWORD,expo:DWORD
; multiply val x10 expo times
  push ebx
  push ecx

  mov eax,val
  mov ecx,expo
  test ecx,ecx
  jz mul10out

    @@:
      lea ebx,[eax*2]
      lea eax,[ebx+eax*8]   ; x2 + x8 = x10
    loop @B

  mul10out:
  pop ecx
  pop ebx
  ret
mul10 endp

isDecChar proc cchar:DWORD
  ; is the low byte of cchar '0'->'9'?
  ; zf=true
  push eax
  mov eax,cchar
  mov ah,1
  cmp al,'0'
  jb @F
    cmp al,'9'
    ja @F
      xor eax,eax
  @@:
  test eax,eax
  pop eax
  ret
isDecChar endp


getDecimal proc saddr:DWORD
; get the integer value of the unsigned decimal string at address saddr
;
; ignores any char that is not a decimal digit ** including '.' **
;----------------------------------------------------------------------
LOCAL retval
  pushad

  ; zero return value
  mov retval,0

  ; get src address
  mov esi,saddr

  ; get string length
  push esi
  call strlen

  ; zero length string?
  test eax,eax
  jz getdecout

  ; add the length to the buffer address
  add esi,eax

  ; esi points to zero terminator so dec
  dec esi

  ; set loop counter to string length
  mov ecx,eax

  ; zero the column number
  xor ebx,ebx

  @@:
    xor edx,edx
    ; get char in dl
    mov dl,[esi]
    dec esi

    ; is the char a decimal digit?
    push edx
    call isDecChar
    ; skip anything else
    jnz skipBadChar

      ; char '0'=48 so subtract this to get that char's value
      sub edx,48

      ; multiply by 10^column number
      push ebx
      push edx
      call mul10

      ; add to return value
      add retval,eax

      ; inc the column number
      inc ebx

    skipBadChar:
  loop @B

  getdecout:
  popad
  mov eax,retval
  ret
getDecimal endp

strDecimal proc daddr:DWORD,val:DWORD
;--------------------------------------------------------
; write unsigned integer val as a decimal string at daddr
;--------------------------------------------------------
  pushad
  mov edi,OFFSET decbuf
  mov ebx,10
  mov eax,val

  ; generate the string
  ;(backwards in decbuf)
  @@:
    ; must clear edx before using div
    xor edx,edx

    ; "div" divides eax by the operand (here ebx=10)
    ; and leaves the remainder in edx, so the remainder
    ; becomes our next digit value, and we continue
    ; until eax=0
    div ebx

    ; add '0' to the remainder to convert
    ; it to an ASCII char
    add dl,48

    ; write the char to the buffer
    mov [edi],dl

    ; inc the buffer ptr
    inc edi

    ; finished?
    test eax,eax
  jnz @B

  ;append a zero terminator
  mov BYTE ptr[edi],0

  ; reverse the string and copy to daddr
  ; (you can work this out, surely ;)
  push OFFSET decbuf
  call strlen

  mov ecx,eax
  add eax,OFFSET decbuf
  mov edi,daddr
  @@:
    dec eax
    mov dl,[eax]
    mov [edi],dl
    inc edi
  loop @B
  mov BYTE ptr[edi],0
  popad
  ret
strDecimal endp

;   Please Note:
;
;   These routines have not been exhaustively tested under all
;   conditions but appeared to function correctly for the task
;   they were written for ( punting smallish integers to and 
;   from a bunch of EditText boxes ).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    相关资源
    最近更新 更多