Author Topic: Convert MASM code to NASM  (Read 21043 times)

Offline Azrael998

  • Jr. Member
  • *
  • Posts: 12
Convert MASM code to NASM
« on: October 27, 2020, 02:39:36 PM »
Hello, everyone, I'm very new to assembly and I'm trying to convert this MASM code to NASM for an assignment, can anyone please help me?. The code is supposed to ask a user for two binary numbers add them then print their sum in binary form.

MASM code is below:

.MODEL SMALL
.STACK 100H

.DATA
  PROMPT_1  DB  0DH,0AH,\'Enter the first binary number ( max 8-digits ) : $\'
  PROMPT_2  DB  0DH,0AH,\'Enter the second binary number ( max 8-digits ) : $\'
  PROMPT_3  DB  0DH,0AH,\'The SUM of given binary numbers in binary form is : $\'
  ILLEGAL   DB  0DH,0AH,\'Illegal character. Try again.$\'

.CODE
  MAIN PROC
    MOV AX, @DATA                ; initialize DS
    MOV DS, AX

    JMP @START_2                 ; jump to label @START_2

    @START_1:                    ; jump label
      LEA DX, ILLEGAL            ; load and display the string ILLEGAL
      MOV AH, 9
      INT 21H

    @START_2:                    ; jump label
      XOR BX, BX                 ; clear BX

      LEA DX, PROMPT_1           ; load and display the string PROMPT_1
      MOV AH, 9
      INT 21H

      MOV CX, 8                  ; initialize loop counter
      MOV AH, 1                  ; set input function

      @LOOP_1:                   ; loop label
        INT 21H                  ; read a character

        CMP AL, 0DH              ; compare AL with CR
        JNE @SKIP_1              ; jump to label @SKIP_1 if AL!=0DH

        CMP CX, 8                ; compare CX with 8
        JE @START_1              ; jump to label @START_1 if CX=8
        JMP @EXIT_LOOP_1         ; jump to label @EXIT_LOOP_1

        @SKIP_1:                 ; jump label
          AND AL, 0FH            ; convert ascii into decimal code
          SHL BL, 1              ; shift BL towards left by 1 position
          OR BL, AL              ; set the LSB of BL with LASB of AL
      LOOP @LOOP_1               ; jump to label @LOOP_1 if CX!=0

      @EXIT_LOOP_1:              ; jump label

      LEA DX, PROMPT_2           ; load and display the string PROMPT_2
      MOV AH, 9
      INT 21H

      MOV CX, 8                  ; initialize loop counter
      MOV AH, 1                  ; set input function

      @LOOP_2:                   ; loop label
        INT 21H                  ; read a character

        CMP AL, 0DH              ; compare AL with CR
        JNE @SKIP_2              ; jump to label @SKIP_2 if AL!=0DH

        CMP CX, 8                ; compare CX with 8
        JE @START_2              ; jump to label @START_2 if CX=8
        JMP @EXIT_LOOP_2         ; jump to label @EXIT_LOOP_2

        @SKIP_2:                 ; jump label
          AND AL, 0FH            ; convert ascii into decimal code
          SHL BH, 1              ; shift BH towards left by 1 position
          OR BH, AL              ; set the LSB of BH with LASB of AL
      LOOP @LOOP_2               ; jump to label @LOOP_2 if CX!=0

      @EXIT_LOOP_2:              ; jump label

      LEA DX, PROMPT_3           ; load and display the string PROMPT_3
      MOV AH, 9
      INT 21H

      ADD BL, BH                 ; add BL and BH
      JNC @SKIP                  ; jump to label @SKIP if CF=1
        MOV AH, 2                ; print the digit 1 i.e. carry
        MOV DL, 31H
        INT 21H

      @SKIP:                     ; jump label

      MOV CX, 8                  ; initialize loop counter
      MOV AH, 2                  ; set output function

      @LOOP_3:                   ; loop label
        SHL BL, 1                ; shift BL towards left by 1 position
        JC @ONE                  ; jump to label @ONE if CF=1
        MOV DL, 30H              ; set DL=0
        JMP @DISPLAY             ; jump to label @DISPLAY

        @ONE:                    ; jump label
          MOV DL, 31H            ; set DL=1

        @DISPLAY:                ; jump label
          INT 21H                ; print the character
      LOOP @LOOP_3               ; jump to label @LOOP_3 if CX!=0

    MOV AH, 4CH                  ; return control to DOS
    INT 21H
  MAIN ENDP
END MAIN

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Convert MASM code to NASM
« Reply #1 on: October 27, 2020, 10:41:51 PM »
Have you assembled this with MASM and tested it? It looks to me like it will never display the error message. I could translate it to nasm code, but you need to get it working first, or at least try fixing it and ask about specific parts that don't work. I can't do all your homework without knowing you have tried :)

If I were to write code to do what you want, I would create macros and/or callable routines.
My graphics card database: www.gpuzoo.com

Offline Azrael998

  • Jr. Member
  • *
  • Posts: 12
Re: Convert MASM code to NASM
« Reply #2 on: October 28, 2020, 01:08:43 AM »
I don't know if this is right but this is what I currently have from reading the Assembly tutorial from tutorialspoint.com. I get the error Segmentation fault (core dumped) when I run the code in my terminal. Can you tell me what the '@' sign does in MASM. I'm only slightly familiar with NASM and I've never used MASM before.

NASM code:

section .data
    msg1 db 'Enter the first binary number: ', 0DH, 0AH
    msg2 db 'Enter the second binary number: ', 0DH, 0AH
    msg3 db 'The sum of the given binary numbers: ', 0DH, 0AH
    illegal   db  'Illegal character. Try again.', 0DH,0AH

section .text
  global _start

_start:

  _start_1:
    lea dx, illegal
    mov ah, 9
    int 21h

  _start_2:
    xor bx, bx

    lea dx, msg1
    mov ah, 9
    int 21h

    mov cx, 8
    mov ah, 1

  _loop_1:
    int 21H

    cmp al, 0DH
    jne _skip_1

    cmp cx, 8
    je _start_1
    jmp _exit_loop_1

  _skip_1:
    and al, 0FH
    shl bl, 1
    loop _loop_1

  _exit_loop_1:
    lea dx, msg1
    mov ah, 9
    int 21H

    mov cx, 8
    mov ah, 1

  _loop_2:
    int 21H

    cmp al, 0DH
    jne _skip_2

    cmp cx, 8
    je _start_2
    jmp _exit_loop_2

  _skip_2:
    and al, 0FH
    shl bh, 1
    or bh, al
    loop _loop_2

  _exit_loop_2:
    lea dx, msg3
    mov ah, 9
    int 21H

    add bl, bh
    jnc _skip
    mov ah, 1
    mov dl, 31H
    int 21H

  _skip:
    mov cx, 8
    mov ah, 2

  _loop_3:
    shl bl, 1
    jc _one
    mov dl, 30H
    jmp _display

  _one:
    mov dl, 31H

  _display:
    int 21H
    loop _loop_3

    mov ah, 4ch
    int 21H
    ret

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Convert MASM code to NASM
« Reply #3 on: October 28, 2020, 02:43:21 AM »
The @ tells masm that it is a label. Your code looks like it is written to be a DOS .com file. I don't know what OS your terminal is running - is it DOS? If not, that might be your problem. You don't need the _ in front of labels unless you are creating object files to link with in C (although it doesn't hurt to have them, they just aren't needed).

Also, the rewritten code will now write the error message then carry on to execute the rest of your code.

When coding, I always start by writing pseudo code (basically mapping out what routines need to happen in what order, and what I need to happen. I find that the easiest and fastest way to get everything working.

I'll take a better look after I have slept, and offer you some better suggestions, then when you have done what you can with them, I'll try to help improve your code. Is this for fun or for school?
My graphics card database: www.gpuzoo.com

Offline Azrael998

  • Jr. Member
  • *
  • Posts: 12
Re: Convert MASM code to NASM
« Reply #4 on: October 28, 2020, 03:03:47 AM »
Thank you very for responding this is for school. My terminal is running on manjaro linux x86_64, the MASM code was written by my professor but I don't know what OS his terminal is running on.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Convert MASM code to NASM
« Reply #5 on: October 28, 2020, 03:57:22 AM »
Hi Azrael998,

Welcome to the forum.

Hi Debs,

This error message sounds like Linux to me. Your Masm code won't run in Linux. In fact, it won't tun on anything but a very old machine or in an emulator = Dosbox or such. This mat ve what you're supposed to be doing. Find out!

We can rewrite this code so it will run in Linux... or you can install Dosbox or some other emulator. Which are you  supposed to be doing?

Good job with the code so far. One problem: "lea" wants "[contents}" of memory. So:
Code: [Select]
lea dx, [illegal]
etc.
The other instructions are mostly the same as Masm.

Hang in there!

Best,
Frank



Offline Azrael998

  • Jr. Member
  • *
  • Posts: 12
Re: Convert MASM code to NASM
« Reply #6 on: October 28, 2020, 05:50:04 AM »
Hi Frank Kotler, thank you very much for responding. My assignment is to convert the code so that it runs on linux, how can I do that?.

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Convert MASM code to NASM
« Reply #7 on: October 28, 2020, 06:36:02 AM »
I don't know the Linux system calls, so won't be able to help with that, but I will reply with some pseudo code later to show how I would code it. I'll leave it to our Linux users to help converting system calls to Linux syscalls.

Does the 8 you are loading into CX mean you are only working with integer strings of 7 digits plus return, or 8 digits without? Do you need to test for overflows (numbers which are too long)? I can see you want to detect invalid key presses.
« Last Edit: October 28, 2020, 06:44:21 AM by debs3759 »
My graphics card database: www.gpuzoo.com

Offline Azrael998

  • Jr. Member
  • *
  • Posts: 12
Re: Convert MASM code to NASM
« Reply #8 on: October 28, 2020, 07:13:04 AM »
The 8 being loaded in the CX register means 8 digits without return, yes I need to test for overflow.

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Convert MASM code to NASM
« Reply #9 on: October 28, 2020, 07:26:31 AM »
Here is some basic pseudo code. I can expand on some of it using code that works on DOS or uses BIOS interrupts, but that would still need changing to use Linus system calls.

section .data
        msg1 db 'Enter the first binary number: ', 0DH, 0AH
        msg2 db 'Enter the second binary number: ', 0DH, 0AH
        msg3 db 'The sum of the given binary numbers: ', 0DH, 0AH
        illegal   db  'Illegal character. Try again.', 0DH,0AH
        str1  times 10 db 0
        str2  times 10 db 0
        result  times 11 db 0



section .text

        org     256           ; only needed if you code for a DOS environment and create a .com file

        read input strings from stdin (normally keyboard)(I would create a callable routine
                                                which takes the output address as its input)
        convert ascii string to binary digits, checking each character as you go.
                                                Store in bh and bl if the systems calls preserve them
        if any input character is invalid, output error msg
        if no errirs, add the resulting numbers
        convert back to am ascii string
        display the output



I made the strings longer than you need so that you can test for input that is too long, as well as having room for the carriage returm (to help check the length of the input). DOS has an interrupt that takes the length of input as an argument, so I assume Linux has that as well,
« Last Edit: October 28, 2020, 07:28:21 AM by debs3759 »
My graphics card database: www.gpuzoo.com

Offline Azrael998

  • Jr. Member
  • *
  • Posts: 12
Re: Convert MASM code to NASM
« Reply #10 on: October 28, 2020, 11:54:20 AM »
I'm planning on rewriting the code do you think it's efficient to convert the binary numbers to decimal then add them then convert the result to binary?

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Convert MASM code to NASM
« Reply #11 on: October 28, 2020, 01:22:53 PM »
As the numbers are being input in ascii text (you are inputting the numbers as ascii codes, not as numbers) I do think it is more efficient, yes. For example, when you type "0", you are not storing 0, you are storing the ascii code, which is 30h (48 decimal). Also, by doing the conversion, you can just add the numbers in both registers (which will set the overflow flag if the result is higher than 0FFh). If you don't convert, you will still have to subtract 30h from each element, then you will have to check each element of the result to see if it is higher than "1". That just seems inefficient to me.

You will also find that, if you write efficient callable routines, they will be reusable in other apps, and will form a template you only need minor adjustments to for similar routines.
My graphics card database: www.gpuzoo.com

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Convert MASM code to NASM
« Reply #12 on: October 29, 2020, 03:36:04 PM »
I have written a similar version to your last post, with some small changes. Personally I would create callable functions for repeated code, but I wanted to keep it as similar to your code as possible, to help you understand the changes.

I kept your labels so you can study each block separately. I always fully comment my code, to make it easier to understand.

This code can be assembled into a DOS .com file. I didn't test it, but believe it is OK. To convert to Linux code, you will need to look up Linux system calls and/or get more help elsewhere.

Code: [Select]
section .data
        msg1 db 'Please enter the first 8-bit binary number: ', 0DH, 0AH
        msg2 db 'Please enter the second 8-bit binary number: ', 0DH, 0AH
        msg3 db  0DH, 0AH, 'The sum of the given binary numbers is:', 0DH, 0AH
        invalid   db  'Invalid input, try again.', 0DH,0AH


section .text

org 100h                                 ; only needed if assembling as a DOS .com file
_start:
        push cs
        pop ds                           ; set data segment

        xor bx, bx                       ; used to store input

        lea dx, msg1                     ;
        mov ah, 9                        ;
        int 21h                          ; output first message using DOS interrupt

        mov cx,8                         ; loop counter
        mov ah,1                         ; DOS int 21h function for keyboard input

_loop_1:
        int 21h                          ; get character input

        sub al,"0"                       ; convert character input to binary digit
        cmp al,1                         ; is input a valid binary digit?
        ja error                         ; if not, jump to error

        shl bl,bl                        ;
        add bl,al                        ; store this character

        loop _loop_1                     ; fetch next digit

        int 21h                          ; fetch final character
        cmp al,0Dh                       ; is this a carriage return?
        ja error                         ; if not, jump to error

        lea dx, msg2                     ;
        mov ah, 9                        ;
        int 21h                          ; output second message using DOS interrupt

        mov cx,8                         ; loop counter
        mov ah,1                         ; DOS int 21h function for keyboard input

_loop_2:
        int 21h                          ; get character input

        sub al,"0"                       ; convert character input to binary digit
        cmp al,1                         ; is input a valid binary digit?
        ja error                         ; if not, jump to error

        shl bh,bh                        ;
        add bh,al                        ; store this character

        loop _loop_2                     ; fetch next digit

        int 21h                          ; fetch final character
        cmp al,0Dh                       ; is this a carriage return?
        ja error                         ; if not, jump to error

        lea dx, msg3                     ;
        mov ah, 9                        ;
        int 21h                          ; output third message using DOS interrupt

        mov ah,2                         ; DOS function 2 outputs a single character
        adc bl,bh                        ; add both numbers, using carry flag for overflow
        jnc _next                        ; if result is only 8-bits, skip this short section

        mov dl,"1"
        int 21h                          ; output "1"

_next:       
        mov cx,8
        xor bh,bh

_loop_3:
        shl bx,1
and bh,1                         ; is next digit 0 or 1?
        jnz _one

        mov dl,"0"                       ; next digit is 0
        jmp _display:

_one:
        mov dl,"1"                       ; next digit is 1

_display
        int 21h                          ; output this character
        loop _loop_3

_exit:
        mov ax,04C00h
        int 21h                          ; exit with error code 0

_error:
        lea dx, invalid                  ;
        mov ah, 9                        ;
        int 21h                          ; output error message using DOS interrupt

        jmp _start:
« Last Edit: October 29, 2020, 03:40:27 PM by debs3759 »
My graphics card database: www.gpuzoo.com