2

I am writing a MASM program using the Irvine32 Library from my textbook. I want to line up my printed columns, but I couldn't finds anything on how to terminate a string with a tab-stop, /t for C/C++, so I made a procedure that determines how many decimal places the number has and assigns the spacer string variable accordingly.

My issue is when trying to assign spacer a new string, I get assembling errors. I have tried

mov spacer, "New String",0

and

mov spacer, "New String"

as well as assigning "New String" to a variable and assigning spacer that variable as well as that variables OFFSET. I now have it where the variables OFFSET is moved into edx but I can't move edx into the other variable.

I would greatly appreciate the help and any information to help be better understand why this doesn't work in assembly or MASM in particular. Thanks

Procedure in question:

; Define the spacer based on the places in x
spacer_choice proc

    cmp x, 10
    JB SC1

    cmp x, 100
    JB SC2

    mov edx, OFFSET hundo_spacer
    JMP SC3

    SC1:
        mov edx, OFFSET one_spacer
        JMP SC3

    SC2:
        mov edx, OFFSET ten_spacer
        JMP SC3

    SC3:
        mov spacer, OFFSET edx
        RET
spacer_choice endp

Output:

1>------ Build started: Project: MASM4, Configuration: Debug Win32 ------
1>  Assembling composite.asm...
1>composite.asm(209): error A2032: invalid use of register
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations\masm.targets(50,5): error MSB3721: The command "ml.exe /c /nologo /Sg /Zi /Fo"Debug\composite.obj" /Fl"MASM4.lst" /I "c:\Irvine" /W3 /errorReport:prompt  /Tacomposite.asm" exited with code 1.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Full Code:

INCLUDE Irvine32.inc

.data
; ----- GLOBALS
n_comps DWORD ?


; ----- INTRO VALUES
; Greeting the User
title_prompt BYTE "Welcome to Prog. 4, my name is Zach", 10, 13, 0
name_prompt BYTE "What should I call you?: ", 0
username BYTE 21 DUP(0)
user_greet BYTE "Hello, ", 0
; Instructing the User
one_instruct BYTE "We are going to calculate all the composite numbers from 1 to n.", 10, 13, 0
two_instruct BYTE "N is the number you enter. That number has to be an integer,", 10, 13, 0
three_instruct BYTE "and in the range of 1 to 400.", 10, 13, 0


; ----- INPUT VALUES
; Prompts
int_prompt BYTE "How many composite numbers do you want to display? 1 to 400: ", 0
bad_prompt BYTE "Your Input was bad, try again", 10, 13, 0
; Constants
MAX_VAL = 400
MIN_VAL = 1


; ----- CALCULATE
x DWORD ?
spacer BYTE ?
count DWORD ?


; ----- SPACER_CHOICE
one_spacer BYTE ",     ", 0
ten_spacer BYTE ",    ", 0
hundo_spacer BYTE ",   ", 0


; ----- OUTRO
farewell BYTE "Hope you've had fun printing composites! Goodbye, ", 0

.code
main proc

    call intro

    call input

    call calculate

    call outro

    invoke ExitProcess, 0
main endp

; Greet the User and get their name
intro proc

    ; Greet
    mov edx, OFFSET title_prompt
    call WriteString

    ; Prompt for username
    mov edx, OFFSET name_prompt
    call WriteString
    mov edx, OFFSET username
    mov ecx, SIZEOF username
    call ReadString
    mov edx, OFFSET user_greet
    call WriteString
    mov edx, OFFSET username
    call WriteString
    call Crlf


    ; Intruct the User
    mov edx, OFFSET one_instruct
    call WriteString
    mov edx, OFFSET two_instruct
    call WriteString
    mov edx, OFFSET three_instruct
    call WriteString
intro endp


; Get User's Input. Validate if Between Min and Max
input proc

    ; Prompt for user input
    I1:
        mov edx, OFFSET int_prompt
        call WriteString
        mov eax, 0
        call ReadInt
        call Crlf


        ; Check if less than MAX_VAL
        cmp eax, MAX_VAL
        JA I4
        JMP I3


        I3:
            ; Check if greater than MIN_VAL
            cmp eax, MIN_VAL
            JB I4
            JMP I2


        I4:
            ; EAX is incorrect
            ; Loop
            mov edx, OFFSET bad_prompt
            call WriteString
    loop I1

    ; Good Input
    ; Set n_comps to eax
    I2:
        mov n_comps, eax
        mov eax, 0
    RET 
input endp


; X is not divisible by 2 or 3, is prime
calculate proc

    mov ecx, 400
    mov x, 1

    C1:
        ; Check if X is less than, or equal to, 3
        cmp x, 3
        JBE C2

        C4:
            ; Check if X is divisible by 2
            mov edx, 0
            mov eax, x
               mov ebx, 2
            div ebx
            cmp edx, 0
            JE C3

            ; Check if X is divisible by 3
            mov edx, 0
            mov eax, x
               mov ebx, 3
            div ebx
            cmp edx, 0
            JNE C2

        C3:
            ; Is composite, Print number
            mov eax, x
            cmp count, 10
            JNE C5

            call Crlf
            mov count, 0

            C5:
                call WriteInt
                call spacer_choice
                mov edx, OFFSET spacer
                call WriteString
                add count, 1

        C2:
            ; RET if X == N
            mov eax, n_comps
            cmp x, eax
            JNE C6

            RET

            C6:
                ; Increment and LOOP
                add x, 1
            LOOP C1
calculate endp


; Define the spacer based on the places in x
spacer_choice proc

    cmp x, 10
    JB SC1

    cmp x, 100
    JB SC2

    mov edx, OFFSET hundo_spacer
    JMP SC3

    SC1:
        mov edx, OFFSET one_spacer
        JMP SC3

    SC2:
        mov edx, OFFSET ten_spacer
        JMP SC3

    SC3:
        mov spacer, OFFSET edx
        RET
spacer_choice endp


; Say Goodbye
outro proc

    mov edx, OFFSET farewell
    call WriteString
    mov edx, OFFSET username
    call WriteString
    call Crlf
outro endp

end main
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
gangwerz
  • 435
  • 2
  • 8
  • 18

1 Answers1

1

I added the ASCII horizontal tab, 9, to the end of spacer, and that removed the need for the spacer_choice procedure.

Spacer now is declared as: spacer BYTE ",", 9, 0

gangwerz
  • 435
  • 2
  • 8
  • 18