Search code examples
assemblyx86number-formattingfasm

Using the fasm, write an x86 assembly program that converts a user-entered integer from -100 to 100 to text


Using the fasm, write an x86 assembly program that converts a user-entered integer from -100 to 100 to text.

Here is an algorithm I recommend:

  1. Ask user to enter a number and store into [Num]
  2. If number is less than 0, output "negative " and change it to positive
  3. Print all the exceptions - check if number is 100, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19. If so, output the number and finish
  4. Divide number by 10 and store answer into [Quotient] and [Remainder]
  5. Compare Quotient to 20, 30, 40, 50, 60, 70, 80, 90 and output ten's digit - e.g. "twenty "
  6. Compare Remainder to 1, 2, 3, 4, 5, 6, 7, 8, 9 and output one's digit - e.g. "five"
  7. Jump to start to repeat entire program

Example output This x86 assembly program converts an integer to text.

Enter an integer from -100 to 100: 73

seventy-three

Enter an integer from -100 to 100: -100

negative one hundred

can anyone please help me out with this program

i mean i wrote the program but quite not able to get the output as expected

format PE console
entry start

include 'win32ax.inc'

section '.data' data readable writable
    Num dd ?
    negative db "negative ", 0
    exceptions db "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", 0
    tens db "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety", 0
    output_msg db "%s", 0
    intro_msg db "This x86 assembly program converts an integer to text.", 0
    input_msg db "Enter an integer from -100 to 100: ", 0

section '.code' code readable executable
start:
    cinvoke printf, intro_msg
    cinvoke printf, input_msg
    cinvoke scanf, "%d", Num     ; Read user input
    
    mov eax, [Num]
    cmp eax, 0
    jge check_exceptions
    
    ; Output "negative " and change to positive
    cinvoke printf, negative
    neg eax
    mov [Num], eax

check_exceptions:
    cmp eax, 100
    je output_result
    
    cmp eax, 0
    je output_exception
    
    cmp eax, 10
    jl divide_by_10
    
    cmp eax, 20
    jl output_tens
    
    mov edx, eax
    shr eax, 1
    shl edx, 31
    sar eax, 31
    xor edx, eax
    sub edx, eax
    movzx eax, dx
    
    lea edx, [exceptions + eax * 4]
    cinvoke printf, output_msg, edx
    
    jmp restart

divide_by_10:
    ; Divide by 10 to get tens and ones digits
    mov ebx, 10
    xor edx, edx
    div ebx
    movzx ecx, dl    ; Remainder is ones digit
    movzx ebx, al    ; Quotient is tens digit
    
    cmp ebx, 0
    je output_ones
    
    ; Output tens digit if not zero
    lea edx, [tens + ebx * 4]
    cinvoke printf, output_msg, edx
    
output_ones:
    cmp ecx, 0
    je restart
    
    ; Output ones digit
    lea edx, [exceptions + ecx * 4]
    cinvoke printf, output_msg, edx
    
    jmp restart

output_tens:
    sub eax, 10
    lea edx, [tens + eax * 4]
    cinvoke printf, output_msg, edx
    
    jmp restart

output_exception:
    lea edx, [exceptions + eax * 4]
    cinvoke printf, output_msg, edx

output_result:
    ; Output the number as text
    lea edx, [exceptions + eax * 4]
    cinvoke printf, output_msg, edx

restart:
    jmp start

section '.idata' import data readable
    library msvcrt, 'msvcrt.dll'
    import msvcrt, printf, 'printf', scanf, 'scanf', ExitProcess, 'ExitProcess'

so after this when i run the program and give the input as 5 the output is something else. please if anyone could help me fix this issue.i would really appreciate it.

Solution

  • i mean i wrote the program but quite not able to get the output as expected

    Now this is something I very much doubt! Are you using an AI of some kind?

    Consider the following:

    mov edx, eax
    shr eax, 1
    shl edx, 31
    sar eax, 31
    xor edx, eax
    sub edx, eax
    movzx eax, dx
        
    lea edx, [exceptions + eax * 4]
    

    What is this crappy code doing here? And why would you expect to reach out to strings of varying lengths (some exceeding 4 characters) with a simple scale by 4?

    cmp eax, 10
    jl divide_by_10
    

    Just another example that makes no sense. Why would a sane person want to divide by 10 if the (positive) number is already smaller than 10?

    Here is an algorithm I recommend:

    Please don't follow that recommendation. Use next idea:

    1. Deal with negative inputs much like you're doing already.
    2. Create a list with all the unique words that you need (no more than 24 in total). The longest word is "seventy". Because it has 7 characters, I suggest you store every word in an 8-byte record. This fixed size will allow using the scaled addressing mode [List+EAX*8].
    3. Create a table with 101 word-sized values whose low byte refers to any of the strings, and whose high byte optionally refers to another one of the strings. Of course matching the remaining inputted numbers [0,100].
    4. Use your inputted number as an index in the table.
    5. Use the word from the table to fetch one or two strings from memory and print them.

    Result: Somewhat more data, but much less (spaghetti) code.