Solve the provided questions below using FASM

99 Views Asked by At

So this is the question:

Using the flat assembler (FASM), write a program that converts an 8-bit integer to binary and hexadecimal using bitwise operators. Do not use external functions. You may use the algorithm below.

Ask user to enter a number 0 - 255 and store into Num

Algorithm to convert Value to binary:

  1. Set Count to 0. Move Num into a variable named Temp
  2. Move Temp into EAX then AND EAX with 128 (binary 10000000)
  3. if result is zero, output "0"
  4. if result is not zero, output "1"
  5. shift Temp left one digit
  6. increment Count
  7. if Count < 8, jump to step (2)

Algorithm to convert Value to hexadecimal:

  1. Move Num into a variable named Temp
  2. shift Temp right 4 digits to isolate left 4 digits
  3. if Temp <=9, print Temp
  4. if Temp >=10, add 55 to Temp and print the ASCII character
  5. Move Num into a variable named Temp
  6. AND Temp with 15 (binary 00001111) to isolate right 4 digits
  7. if Temp <=9, print Value
  8. if Temp >=10, add 55 to Temp and print the ASCII character

Example output:

This x86 assembly program converts an integer to binary and hex.

Enter an integer from 0 - 255: 73
Binary: 01001001
Hex:    49

This is how I attempted it:

format PE console
include 'win32ax.inc'
section '.code' code readable executable
start:
                cinvoke printf, "Enter an integer from 0-255:"
                cinvoke scanf, "%d", Num
                call BinStep1
                call HexStep1
                cinvoke printf, "%c%c", 10,10
                jmp start

BinStep1:
        cinvoke printf, "%cBin:",10
        mov [Count],0
        mov eax, [Num]
        mov [Temp], eax

BinStep2:
        mov eax, [Temp]
        and eax, 128 ; result is either 0 or 128

BinStep3:
        jnz BinStep4
        ;output a zero
        jmp BinStep5

BinStep4:
        ;output a one

BinStep5:
        ;shift temp left one digit

BinStep6:
        ;increment Count

BinStep7:
        cmp[Count], 8
        jl BinStep2
        ret

HexStep1:
        cinvoke printf, "%cHex: ",10
        mov eax, [Num]
        mov [Temp], eax

HexStep2:
        shr [Temp], 4
        call PrintHexDigit

HexStep5:
        mov eax, [Num]
        mov [Temp], eax

HexStep6:
        ;And Temp with 15 to isolate right 4 bits
        call PrintHexDigit
        ret

PrintHexDigit:
             cmp [Temp],9
             jp GreaterThan9
             cinvoke printf, "%d", [Temp]
             ret

GreaterThan9: ;print A-F
              add [Temp], 55
              cinvoke printf, "%c",[Temp]
              ret



section '.data' data readable writeable

Num   dd  0
Temp  dd  0
Count dd  0


section '.idata' import data readable

library msvcrt,'msvcrt.dll',kerne132,'kerne132.dll'
import msvcrt, printf,'printf',scanf,'scanf'

But my results did not came out as expected. This is how the output came out:

output after I run the program

Can anyone help me out in fixing this program?

1

There are 1 best solutions below

0
Sep Roland On

BinStep

   ;output a zero

   ;output a one

   ;shift temp left one digit

   ;increment Count

But my results did not came out as expected.

I wonder, did you expect something to come out when you didn't even replace the comments by actual instructions?
And anyway, the BinStep loop is really an infinite loop, because not incrementing Count will bring about that cmp [Count], 8 jl BinStep2 will always be true and therefore forever jumping to the top of the loop!

BinStep1:
        cinvoke printf, "%cBinary:",10
        mov [Count],0
        mov eax, [Num]
        mov [Temp], eax

BinStep2:
        mov eax, [Temp]
        and eax, 128           ; result is either 0 or 128

BinStep3:
        jnz BinStep4
        cinvoke printf "0"     ;output a zero
        jmp BinStep5

BinStep4:
        cinvoke printf "1"     ;output a one

BinStep5:
        shl [Temp], 1          ;shift temp left one digit

BinStep6:
        inc [Count]            ;increment Count

BinStep7:
        cmp [Count], 8
        jl  BinStep2
        ret

HexStep

   ;And Temp with 15 to isolate right 4 bits

Again I see a comment that didn't get translated to assembly. Just as easy as the shr [Temp], 4 that you knew about, this needs to become and [Temp], 15.
The PrintHexDigit subroutine has a typo. The jp GreaterThan9 instruction is testing the parity flag. What you need is jg GreaterThan9

HexStep1:
        cinvoke printf, "%cHex:   ",10
        mov  eax, [Num]
        mov  [Temp], eax

HexStep2:
        shr  [Temp], 4
        call PrintHexDigit

HexStep5:
        mov  eax, [Num]
        mov  [Temp], eax

HexStep6:
        and  [Temp], 15        ;And Temp with 15 to isolate right 4 bits
        call PrintHexDigit     <<< Tail-call
        ret

PrintHexDigit:
        cmp  [Temp], 9
        jg   GreaterThan9
        cinvoke printf, "%d", [Temp]
        ret

GreaterThan9: ;print A-F
        add  [Temp], 55
        cinvoke printf, "%c", [Temp]
        ret

I fully understand that you want to follow the provided algorithms to the letter, but you could remove that tail-call from the HexStep and still comply:

HexStep1:
        cinvoke printf, "%cHex:   ",10
        mov  eax, [Num]
        mov  [Temp], eax
        shr  [Temp], 4
        call .Hex
        mov  eax, [Num]
        mov  [Temp], eax
        and  [Temp], 15
.Hex:   cmp  [Temp], 9
        jg   .GT9
        cinvoke printf, "%d", [Temp]
        ret
.GT9:   add  [Temp], 55
        cinvoke printf, "%c", [Temp]
        ret