News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

symbol redefinition error

Started by shaqywacky, August 14, 2011, 06:14:19 PM

Previous topic - Next topic

shaqywacky

Hello everyone, I'm pretty new to assembler, so this might be really obvious. 

Just as an exercise I tried to write a decimal to ascii converter but I keep getting this error: "/masm32/include/masm32.inc(402) : error A2005: symbol redefinition : RUN_SYNCH_PROCESS_EX".  Obviously I can stop the error if I don't include masm32.inc but I need it.  Here's the code:

.386

.MODEL flat, stdcall

include /masm32/include/kernel32.inc
includelib /masm32/inc/kernel32.lib
include /masm32/include/masm32.inc
includelib /masm32/lib/masm32.lib





.DATA
number1 DWORD 7845
string1 BYTE 10 DUP(?),0

D1_dtoa PROTO :DWORD, :DWORD



.CODE

start:
    ;invokes the main process
    invoke D1_dtoa, number1, addr string1
   
    ;exits
    invoke ExitProcess, 0
end start





D1_dtoa PROC num1:DWORD, dest1:DWORD
  LOCAL num1 :DWORD
  LOCAL dest1 :DWORD

  ;saves all the variables
    push ebp
    mov ebp, esp

    push eax
    push ebx
    push ecx
    push edx
    push esi
    push edi
   
    ;moves local variables into ebx and edi
    mov ebx, num
    mov edi, dest
   
   
    ;checks if it is negative or not, puts a minus sign if it is, a space if it isn't
    ;This should save the sign bit and apply it at the end, I'll fix this later
    cmp ebx, 0
    jge not_negative
    mov edx, '-'
    mov [edi], edx
    jmp negative
    not_negative:
    mov edx, ' '
    mov [edi], edx
    negative:
    inc edi
   
   
    ;Divide by 10 and put remainder in the low part of the string
    ; end when ecx = 0 or eax = 0, quit
    mov ecx, 9
    .WHILE ecx > 0
     
      mov edx, 10
      mov eax, ebx
      idiv edx
      .IF eax == 0
        .BREAK
      .ENDIF
      sub esi, ecx
      mov [esi], edx
      add esi, ecx
      dec ecx
    .ENDW
   
    ; fill in the rest with zeros.  This is dumb and I'll fix it later
    mov edx, 0
    .WHILE ecx > 0
      sub esi, ecx
      mov [esi], edx
      add esi, ecx
      dec ecx
    .ENDW
   
    pop edi
    pop esi
    pop edx
    pop ecx
    pop ebx
    pop eax
    pop ebp
   
    ret


D1_dtoa ENDP


END

I know there are probably a lot of dumb things I did(like very little comments, and manually saving the registers), so if you see something that doesn't have to do with main question but is bad assembly practice, feel free to tell me.

I tried changing all my variable names(that's why they all have a number one in them) but that didn't solve the problem.

I don't know if it matters but I tired assembling with this command:

ml /c /coff test.asm


I'd really appricate some help.

Thanks :bg


Gunner

~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

shaqywacky

Thanks, that fixed that problem.

Unfortunately there seem to be another one.  When I try to link it I get this error: "d.obj : error LNK2001: unresolved external symbol _D1_dtoa@8".

Here's the code with the changes:

.386

.MODEL flat, stdcall
option casemap:none

include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
includelib /masm32/lib/kernel32.lib
include /masm32/include/masm32.inc
includelib /masm32/lib/masm32.lib


.DATA
number1 DWORD 7845
string1 BYTE 10 DUP(?),0

D1_dtoa PROTO :DWORD, :DWORD

.CODE

start:
    ;invokes the main process
    invoke D1_dtoa, number1, addr string1
   
    ;exits
    invoke ExitProcess, 0
end start



D1_dtoa PROC num1:DWORD, dest1:DWORD
  LOCAL num1 :DWORD
  LOCAL dest1 :DWORD

  ;saves all the variables
    push ebp
    mov ebp, esp

    push eax
    push ebx
    push ecx
    push edx
    push esi
    push edi
   
    ;moves local variables into ebx and edi
    mov ebx, num
    mov edi, dest
   
   
    ;checks if it is negative or not, puts a minus sign if it is, a space if it isn't
    ;This should save the sign bit and apply it at the end, I'll fix this later
    cmp ebx, 0
    jge not_negative
    mov edx, '-'
    mov [edi], edx
    jmp negative
    not_negative:
    mov edx, ' '
    mov [edi], edx
    negative:
    inc edi
   
   
    ;Divide by 10 and put remainder in the low part of the string
    ; end when ecx = 0 or eax = 0, quit
    mov ecx, 9
    .WHILE ecx > 0
      mov edx, 10
      mov eax, ebx
      idiv edx
      .IF eax == 0
        .BREAK
      .ENDIF
      sub esi, ecx
      mov [esi], edx
      add esi, ecx
      dec ecx
    .ENDW
   
   
    ; fill in the rest with zeros.  This is dumb and I'll fix it later
    mov edx, 0
    .WHILE ecx > 0
      sub esi, ecx
      mov [esi], edx
      add esi, ecx
      dec ecx
    .ENDW
   
   
    ; restore regisiters
    pop edi
    pop esi
    pop edx
    pop ecx
    pop ebx
    pop eax
    pop ebp
   
    ret

end D1_dtoa

END

I'm thinking it has to do with how I'm invoking procedures, I haven't done it a whole lot so I could easily be messing it up.

Thanks.

dedndave

it is simpler to use the masm32rt.inc file for your preamble
as for the new error, you just need a prototype

get rid of all this stuff...
.386

.MODEL flat, stdcall
option casemap:none

include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
includelib /masm32/lib/kernel32.lib
include /masm32/include/masm32.inc
includelib /masm32/lib/masm32.lib


and replace it with this...
        INCLUDE \masm32\include\masm32rt.inc

D1_dtoa PROTO   :DWORD,:DWORD


take a look inside the \masm32\include\masm32rt.inc file to see what it does for you

Gunner

Um...

you have

start:
...
...
...
end start

someproc proc

end someproc

end





Not correct

should be


start:
...
...
ExitProcess, 0

your procs here


end start






and to define the start and end of a proc it should be:


MyProc proc

MyProc endp


notice the endp for end proc
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

dedndave

also, there is no need to preserve EAX, ECX, or EDX
these 3 registers are normally used to return result and/or status (especially EAX)
i try to use all 3 - even when i don't need them
in this case, you might return:
EAX = 0 if no errors occur, otherwise an error code
ECX = length of result
EDX = address of result

this makes it very convenient to use the function

Gunner

Quote from: dedndave on August 14, 2011, 07:22:40 PM
it is simpler to use the masm32rt.inc file for your preamble
as for the new error, you just need a prototype

get rid of all this stuff...
.386

.MODEL flat, stdcall
option casemap:none

include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
includelib /masm32/lib/kernel32.lib
include /masm32/include/masm32.inc
includelib /masm32/lib/masm32.lib


and replace it with this...
        INCLUDE \masm32\include\masm32rt.inc

D1_dtoa PROTO   :DWORD,:DWORD


take a look inside the \masm32\include\masm32rt.inc file to see what it does for you

He already has a proto...

Make the changes in my post and all will work  :bg
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

dedndave

oh - so he does - lol
i didn't see it down there hidden away   :P

we generally put PROTOtypes right after the INCLUDE's
then STRUCTures
then MACRO's
then EQUates
then DATA

shaqywacky

Quote
it is simpler to use the masm32rt.inc file for your preamble
I was just thinking about making something like that because I was getting tired of typing all that in every time.  Thanks, that should make it nicer.

@Gunner
That clears a lot up, I was pretty confused about how that was all structured.  So basically the program will start running automatically after the first thing that is in the form <name>: and it will stop at "end" or if it hits a ExitProcess?

Quote
we generally put PROTOtypes right after the INCLUDE's
then STRUCTures
then MACRO's
then EQUates
then DATA
That was another thing I was confused about, I just randomly put PROTOs in and I wasn't sure if it mattered or not.  That make sense.

Thanks guys!

dedndave

well - those aren't hard-and-fast rules
it just helps the flow

for example, you may reference an invoked function inside a macro, so we define prototypes first
we may want some equates up there, also - so we re-arrange things a bit
you get the idea

quite often, for larger projects, the prototypes, structures, macros, and equates go into a project INC file

Gunner

Yuppers, once you start working on a large project (or any size really) it is good to put everything in a separate inc file

All my .data goes in strings.inc, all .data? goes in data.inc, protos in protos.inc, structures in struct.inc etc...  then you just include them as any other include file
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com