News:

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

(first) MASM Code not working..

Started by n00b!, May 23, 2008, 02:32:30 PM

Previous topic - Next topic

n00b!

Hello, I'm trying to code in MASM and this is the result:

The Assembler gives out much errors, but I don't know how to fix them, since I'm a Newbie in ASM/MASM..

Could somebody fix my code and maybe explain me, what I did wrong, why it's wrong and how to do it right?

That's would be awesome, Thanks!

Tedd

Rather than correcting every mistake, I'll point you in the right direction - then you can have fun fixing, plus you'll remember better in future :bdg

So, your main mistake is trying to use 2 memory accesses (variables and function parameters are memory access) in one instruction - x86 instructions generally only allow one memory access, so to do most things you'll need to go through a register..

Example:
cmp pos, len

is invalid because it attempts to use two parameters in the same instruction.

Solution:
mov eax, pos
cmp eax, len


"mov [myvar + pos], [abc + i]" and "test [abc + i], [abc + i]" are more examples... although they have the additional complication of trying to do even more things at once - happy hunting.

Just remember: one instruction should only do one thing (getting a variable is one thing, adding two numbers is one thing, copying a value is one thing..)
No snowflake in an avalanche feels responsible.

n00b!

#2
Thanks for your reply!

1.
mov [myvar + pos], [abc + i]

Can i write
mov eax, [abc + i]
mov [myvar + pos], eax

?

2.
mov eax, pos
cmp eax, len


Does
mov eax, pos
cmp len, eax
work, too?

PS: Do you know how "lea" works and what it does?

Thanks in advance..

EDIT:
Oh, wait..
In [abc + i] are 2 variables... so it won't work...

mov eax, i
[abc + eax]

Is this correct?

PS2: I can use ecx as iteration-variable, right?
But since it's a global register, i cannot use it as seperate cell in a recursion... is this so?

Moddy

Quote from: n00b! on May 23, 2008, 04:53:18 PM
PS: Do you know how "lea" works and what it does?

Thanks in advance..

lea = Load Effective Address

http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_6/CH06-1.html#HEADING1-136 That should explain what the instruction does.

hutch--

Noob,

You have a few basic thingds to learn including the info that Tedd has told you. With assembler instructions you do not have in the normal sense "syntax errors", there are a published set of instructions (mnemonics) that directly represent hardware opcodes in the processor. With an Intel compatible notation assembler like MASM you have a notation for what is called the "complex addressing modes" which are normally enclosed in square brackets that have a very specific form dictated by the range of available opcodes in the processor.

Double memory operands (cmp mem, mem) do not have a corresponding opcode to assemble to, you must put at least one into a register to perform the comparison, data movement or operation.

The complex addressing modes cannot be used for memory variables added together like a high level language. They have a very clear set of rules in how you use them,

1. Base address (register or a leading displacement).
2. Index register.
3. Scaling factor for index register (1,2,4,8)
4. Displacement in bytes added to address.

You can get code like this from it.


mov eax, [ebx+ecx*4+64]
base address EBX plus index register ECX times scaling factor of 4 plus 64 bytes.


It takes a bit of work to get used to this complex addressing mode but the results are very fast and very clear once you get the swing of it.

LATER: Here is a quick rewrite that probably does what you were trying to do. There was a lot wrong with your original code so try and get the swing of what has been changed and why its been changed.


; ----------------------------------------

    .486
    .model flat, stdcall
    option casemap :none

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\user32.inc

    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\user32.lib

  ; -----------------------------------------
  ; don't put prototypes in the .CODE section
  ; -----------------------------------------
    func1 PROTO :DWORD,:DWORD
    func2 PROTO :DWORD

    .DATA
      txt db "txtdefgh", 0
      mbttl db "Result",0

    .DATA?
      myvar db 64 dup (?)

    .CODE

; ----------------------------------------

start:
    push 4
    push 0
    call func1
    invoke ExitProcess, 0

; ----------------------------------------

func1 proc pos:DWORD, len:DWORD

    push esi
    push edi

    mov eax, len
    cmp pos, eax
    jg quit

    mov esi, OFFSET txt     ; the text address
    mov edi, OFFSET myvar   ; the destination buffer
    mov ecx, LENGTHOF txt   ; the length of the text
    rep movsb               ; copy txt to myvar

    push OFFSET myvar       ; push the result address
    call func2              ; call procedure to display the result

  quit:
    pop edi
    pop esi

    ret

func1 endp

; ----------------------------------------

func2 proc s:DWORD
    invoke MessageBox, NULL, s, OFFSET mbttl, MB_OK
    ret
func2 endp

; ----------------------------------------

end start
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

hutch--

Here is a variation tha shows some simple code that uses the complex addressing mode correctly.


; ----------------------------------------

func1 proc pos:DWORD, len:DWORD

    push esi

    mov eax, len
    cmp pos, eax
    jg quit

  ; ESI and EDX are two seperate BASE addresses.

    mov esi, OFFSET txt         ; the text address
    mov edx, OFFSET myvar       ; the destination buffer

    or ecx, -1                  ; use ECX as the INDEX
  @@:
    add ecx, 1                  ; add 1 to the index each iteration of the loop
    mov al, BYTE PTR [esi+ecx]  ; copy byte from source
    mov BYTE PTR [edx+ecx], al  ; write it to destination
    test al, al                 ; check if its an ASCII zero
    jnz @B                      ; loop back if it is not

    push OFFSET myvar           ; push the result address
    call func2                  ; call procedure to display the result

  quit:
    pop esi

    ret

func1 endp

; ----------------------------------------


The code starts with the two base addresses and increments the INDEX for both addresses, it tests at the end of the loop if the character is the ASCII zero terminator and exits the loop if it is.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

n00b!

#6
Thank you all very much!!! :-)