News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

LNK2001: unresolved external symbol _mainCRTStartup

Started by totosayen_cpp, April 28, 2021, 05:46:12 PM

Previous topic - Next topic

totosayen_cpp

Hello everyone,
Before starting, I'd like to say that I'm new on this forum, so I hope I've posted at the good place (if it's not the case, I'm sorry).
I took a look on the forum and I saw that this error appears frequently.
There's my code :

.386
.model flat, stdcall
.stack 1000h ; 4096-sized stack
option casemap : none ; differencies uppercase chars and lowercase ones

include msvcrt.inc
include masm32rt.inc
include masm32.inc
include masm32/m32lib/ltoa.asm ; without, error A2008 syntax error ltoa

includelib masm32.lib
includelib msvcrt.lib
includelib masm32rt.lib

.data
Hello db "Hello, World !", 13, 10 ; string ended with opcode 10 => endline

.data?
value db 64 dup (?)
; according to masm help (help/masmlib section conversion/atoi), 128 bytes are usually sufficient for input, a word is 2 bytes long

.code

main proc
invoke StdOut, addr Hello
invoke StdIn, addr value, 64
mov eax, atol value
add eax, 1
new db " "
ltoa new, addr value
invoke StdOut, addr new

main endp

end main


I found a topic where the error disappeared with the final 'end main', but it doesn't work for me.

That's the command line :

C:/masm32/bin/ml.exe /c /coff /Cp /nologo /I"C:/" /I"C:/masm32/include/" %file%
C:/masm32/bin/link.exe /subsystem:console /release /version:4.0 /libpath:"C:/" /libpath:"C:/masm32/lib" /out:%app%.exe %app%.obj

(file and app are <path>/<filename>.asm and <path>/<filename>, no problem with that)

I know there's print macro os MasmBasic lib by @jj2007 but to start, I'd like to understand I/O system in assembly before hide complexity (in another topic, I saw that a display requires 4 lines, right ?).

If it can help you, my final goal is to input two numbers, then display their sum.
But when I tried (with another program) to add two inputs, it displays the char corresponding to the sum of ASCII values.
How can I do ?

(I'm sorry if my English isn't very good, that's not my first language)

hutch--

Hi an welcome on board.

.stack 1000h   ; this is not used in Win32. Stack is set in the linker options if you need to.

include masm32rt.inc  ; use this line by itself, it include the normal range of options.

You need a layout like this.

    include \masm32\include\masm32rt.inc
   
    .code

start:

    ; all of your code.

end start

totosayen_cpp

So I write main: ... end main, and it works.
I don't need to change the stack's size, but I saw it on Internet.

The layout is correct because in the command line, I wrote /I"C:/masm32/include" and /I"C:/".
But ltoa doesn't seem to be recognized by the linker :
test.asm(24) : error A2008: syntax error : ltoa
test.asm(21) : error A2206: missing operator in expression

(Is this site based in Australia ? It's quite weird for m to see 06PM, because in France it's almost 11AM)

daydreamer

Welcome totosayen_cpp :thumbsup:
you need to put
new db " " in .data section
end strings with 0
"this is a string",0
and invoke ltoa in similar way you do with other PROC's like
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

totosayen_cpp

#4
Thank you for this welcome !

So, I did some changes (inputs a number, adds 1 and displays the result) :

.386
.model flat, stdcall
option casemap : none ; differencies uppercase chars and lowercase ones

include masm32rt.inc

includelib masm32rt.lib

.data
Hello db "Hello, World !", 13, 10, 0 ; string ended with opcode 10 => endline
new db " ", 0

.data?
value db 64 dup (?)
; according to masm help (help/masmlib section conversion/atoi), 128 bytes are usually sufficient for input, a word is 2 bytes long

.code

main:
invoke StdOut, addr Hello
invoke StdIn, addr value, 64
invoke atol, addr value
add value, 1
invoke ltoa, addr value, addr new
invoke StdOut, addr new
invoke ExitProcess, 0
end main


It compiles and links, but the output seems quite odd.
The program firstly displays "Hello, World !" followed by an endline, as expected.
Then, I input 8 and it ouputs 4206624.

Why this result ?

hutch--

The "Hello World" is string data where 8 is an integer. Use a string conversion to make 8 into a displayable string.

jj2007

You will fail miserably if you don't practice two things:
1. read the documentation carefully, and try to really understand it
2. comment your code thoroughly

include \masm32\include\masm32rt.inc

.data
Hello db "Hello, World !", 13, 10, 0 ; string ended with opcode 10 => endline
new db " ", 0

.data?
value dd ?
buffer db 64 dup (?)   ; this buffer serves for what we type
; according to masm help (help/masmlib section conversion/atoi), 128 bytes are usually sufficient for input, a word is 2 bytes long

.code

main:
invoke StdOut, addr Hello
invoke StdIn, addr buffer, 64 ; get a string into the buffer
invoke atol, addr buffer ; convert to a long ("ascii to long")
mov value, eax ; the value was returned in eax
add value, 100 ; add something
invoke ltoa, value, addr new ; convert long to ascii
invoke StdOut, addr new ; print it
invoke ExitProcess, 0
end main

hutch--

Hi Toto,

Here is a simple test piece that may be useful to you.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include\masm32rt.inc
   
    .code

start:

    call testbed                        ; call the testbed proc
    exit                                ; the exit macro

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

testbed proc

    LOCAL var1  :DWORD                  ; create local variables
    LOCAL var2  :DWORD
    LOCAL rslt  :DWORD

    mov var1, 100                       ; load immediate values into variables
    mov var2, 150

    mov eax, var1                       ; load 1st variable into EAX register
    add eax, var2                       ; add var2 to EAX
    mov rslt, eax                       ; store EAX register in variable

    print "Total = "                    ; display leading text
    print ustr$(rslt),13,10             ; display calculation result

    inkey                               ; pause to view the output

    ret

testbed endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start

totosayen_cpp

Thank you @jj2007, I've read masm32/help/masmlib.chm (conversions/atol) and it doesn't (at least for me) say where the result is stored.
I'm sorry and I'll try to search more the next time.

I'm trying this to input the values :

include masm32rt.inc

.data
Hello   db  "Hello, World !", 13, 10, 0 ; string ended with opcode 10 => endline
input1  db "Input a number : "      , 0
input2  db "Input another number : ", 0
plus db " + " , 0
equal db " = " , 0
endline db " ", 13, 10 , 0

.data?
resultInt dd ? ; result (integer) of the 2 numbers
resultStr db ? ; result (string) of the 2 numbers

; according to masm help (help/masmlib section conversion/atoi), 128 bytes are usually sufficient for input, a word is 2 bytes long

buffer1  db 64 dup (?)   ; stores input 1
buffer2  db 64 dup (?) ; stores input 2

.code

inputValue proc text: dword, buffer: dword, value: dword
invoke StdOut, text ; displays text
invoke StdIn, buffer, sizeof buffer ; inputs string
invoke atol, buffer ; converts it into a signed number (dword)
add value, eax ; result stored in eax
mov eax, 0 ; resets eax
invoke StdOut, addr endline ; writes a new line to clean output
ret
inputValue endp

main:
; inputs the two values
invoke inputValue, addr input1, addr buffer1, addr resultInt
invoke inputValue, addr input2, addr buffer2, addr resultInt

; converts back value into a string
invoke ltoa, resultInt, addr resultStr

; displays the result
invoke StdOut, addr buffer1
invoke StdOut, addr plus
invoke StdOut, addr buffer2
invoke StdOut, addr equal
invoke StdOut, addr resultStr
invoke StdOut, addr endline

; ends the process
invoke ExitProcess, 0
end main


But it doesn't work as expected :

  • The result is always 0 (if I remove addr of resultInt, it doesn't work; if I declare value param as a lpvoid compilation fails (undefined symbol))
  • When displaying, the first buffer seems empty, whereas the second displays well (with the 2nd input)

jj2007

invoke StdIn, buffer, sizeof buffer ; inputs string

Are you sure this is the right "sizeof buffer"? The local argument buffer is a DWORD, i.e. its size is 4 bytes :cool:

totosayen_cpp

So, is there a way to "dereference" the pointer ?
In C we do :

type func(type* ptr) {
    type val = *ptr;
}


How do you write invoke StdIn, buffer sizeof <dereferenced buffer> ?

jj2007

invoke StdIn, buffer, sizeof buffer1 will work. If you insist on following the rules, add another argument to the proc:

inputValue proc text: dword, buffer: dword, value: dword, TheSize
invoke StdIn, buffer, TheSize
...

invoke inputValue, addr input1, addr buffer1, addr resultInt, sizeof buffer1

Better, avoiding misunderstandings:
inputValue proc text: dword, pBuffer: dword, value: dword, TheSize
invoke StdIn, pBuffer, TheSize
...
invoke inputValue, addr input1, addr buffer1, addr resultInt, sizeof buffer1

totosayen_cpp

I added a paramater :

inputValue proc text: dword, buffer: dword, bufferSize: word, value: dword
...
invoke StdIn, buffer, bufferSize
...
inputValue endp

; main :
invoke inputValue, addr input1, addr buffer1, sizeof buffer1, addr resultInt


But I've the same problem (console log) :
Quote
***********
ASCII build
***********

Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Input a number : 7

Input another number : 4

+ 4 = 0

jj2007

Please post your complete code with comments.

invoke inputValue, addr input1, addr buffer1, sizeof buffer1, addr resultInt
invoke inputValue, addr input2, addr buffer2, sizeof buffer2, addr resultInt

; converts back value into a string
invoke ltoa, resultInt, addr resultStr

totosayen_cpp

Sorry, that's the whole code :

include masm32rt.inc

.data
Hello   db  "Hello, World !", 13, 10, 0 ; string ended with opcode 10 => endline
input1  db "Input a number : "      , 0
input2  db "Input another number : ", 0
plus db " + " , 0
equal db " = " , 0
endline db " ", 13, 10 , 0

.data?
resultInt dd ? ; result (integer) of the 2 numbers
resultStr db ? ; result (string) of the 2 numbers

; according to masm help (help/masmlib section conversion/atoi), 128 bytes are usually sufficient for input, a word is 2 bytes long

buffer1  db 64 dup (?)   ; stores input 1
buffer2  db 64 dup (?) ; stores input 2

.code

inputValue proc text: dword, buffer: dword, bufferSize: word, value: dword
invoke StdOut, text ; displays text
invoke StdIn, buffer, bufferSize ; inputs string
invoke atol, buffer ; converts it into a signed number (dword)
add value, eax ; result stored in eax
mov eax, 0 ; resets eax
invoke StdOut, addr endline ; writes a new line to clean output
ret
inputValue endp

main:
; inputs the two values
invoke inputValue, addr input1, addr buffer1, sizeof buffer1, addr resultInt
invoke inputValue, addr input2, addr buffer2, sizeof buffer2, addr resultInt

; converts back value into a string
invoke ltoa, resultInt, addr resultStr

; displays the result
invoke StdOut, addr buffer1
invoke StdOut, addr plus
invoke StdOut, addr buffer2
invoke StdOut, addr equal
invoke StdOut, addr resultStr
invoke StdOut, addr endline

; ends the process
invoke ExitProcess, 0
end main