Search code examples
nasmfpu

nasm infinite loop with FPU


i'm trying to create a small nasm program which do this operation in floating point

while(input <= 10^5) do
begin
   input = input * 10
   i = i - 1
end

the equivilant program in nasm is as following

section .data

    input: resd 1
    n10: dd 0x41200000          ; 10

_start:
    mov eax, 0x43480000        ; eax = 200

    mov dword [input], eax      ; input = eax = 200
    mov edx, 0x49742400         ; 10^5

    ; %begin
    mov ecx, 0                  ; i = 0
    jmp alpha

alpha:
    cmp [input], edx            ; input <= 10^5
    jle _while                  
    jmp log2

_while:
    fld dword [input]            ; input
    fmul dword [n10]                ; input * 10
    fst dword [input]            ; input = input
    dec ecx                      ; i = i - 1
    jmp alpha

the _while loop is iterating infinitely

ecx / i gards always the same value = 0 (it is sepposed to be 0) and doesn't decrement


Solution

  • This works for me (tested in DosBox):

    org 0x100
    bits 16
    
    _start:
    mov dword [input], __float32__(99.0)
    mov edx, __float32__(10000.0)  
    
    mov ecx, 0                  ; i = 0
    jmp alpha
    
    alpha:
    cmp [input],edx            ; input <= 10^5
    jle _while                  
    jmp log2
    
    _while:
    fld dword [input]            ; input
    fmul dword [n10]                ; input * 10
    fstp dword [input]            ; input = input
    inc ecx                      ; i = i - 1
    jmp alpha
    
    log2:
    
    ; print the value of cl
    mov dl,cl
    add dl,'0'
    mov ah,2
    int 21h
    
    ; Exit to DOS
    mov ah,0x4c
    int 21h
    
    n10: dd 10.0 
    input: resd 1
    

    Note the bits 16 which tells nasm that 16-bit operands are the default and that instructions using 32-bit operands should be prefixed. Without this your code would be seen as gibberish if you try to execute it in a real-mode environment.
    It's possible that you'll need to use bits 32 instead, depending on your target environment.
    Also note the use of floating-point literals rather than hex values (you had a typo in your code where you compared against 10^6 instead of 10^5).