Author Topic: New to NASM syntax  (Read 10416 times)

nobody

  • Guest
New to NASM syntax
« on: January 31, 2005, 04:18:08 PM »
Hey.

I have programmed in ASM, mainly 32 bit, for some time, but using MASM syntax. Compared to NASM, it's relatively easy, since it has all extra directives such as ADDR, and OFFSET, and then it has macros.

I am writing an operating system, just for the learning.

And what I need to know, I will express in example code.

Say we have a string:

string db "String",0x0d,0x0a,0

And I would want to do some kind of loop, comparing the text to 0, that is the end of the string, and if then exit on zero.

In masm syntax, I would do something like:

mov al,[string+cx] ; CX being the index for the loop.

How would I go about doing that?

My friend explained to me, very vaguely, something like "mov al,byte[string+1]", but that gives me the "invalid effective address".

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: New to NASM syntax
« Reply #1 on: January 31, 2005, 06:52:24 PM »
> I have programmed in ASM, mainly 32 bit, for some time, but using MASM syntax.
> Compared to NASM, it's relatively easy, since it has all extra directives such
> as ADDR, and OFFSET, and then it has macros.

Okay, *cough*, if you say so... Nasm users seem to get along without "OFFSET"... What does "ADDR" do?

> I am writing an operating system, just for the learning.

Okay, are we still in the 16-bit part, or 32-bit? (your example seems to be 16-bit, so I'll assume that...)

> And what I need to know, I will express in example code.
>
> Say we have a string:
>
> string db "String",0x0d,0x0a,0
>
> And I would want to do some kind of loop, comparing the text to 0, that is the
> end of the string, and if then exit on zero.

Okay... you need "strlen", or just to find the end of it? Something like...

xor si, si
find_len:
    cmp byte [string + si], 0
    jz got_len
    inc si
    jmp short find_len
got_len:

Now si has the length. Note that Nasm doesn't "remember" that we said "string" was "db", so we *do* need the "byte" size-specifier, but Nasm users get along without "PTR", too. Also, Nasm (without the "-O" switch) defaults to a "near" jump - the "short" tells Nasm that the target is within signed-byte range. (the code would just be longer without it - it would still work)

> In masm syntax, I would do something like:
>
> mov al,[string+cx] ; CX being the index for the loop.
>
> How would I go about doing that?

Use a different processor than x86? I'll eat my linker if that works in Masm syntax! Using 16-bit instructions, only bx, si, di, and bp can by used in an "effective address". "mov al, [string + ecx] would be okay... You can use 32-bit instructions in 16-bit code if you want to. It involves a 67h address size overwrite byte. Make sure that the upper word of ecx is clear. Nasm doesn't require a directive like ".386" to enable 32-bit instructions. ("cpu 386" would cause an error if an instruction not available until *after* 386 was used - not quite the same thing. By default, Nasm allows *any* instruction - programmer's responsibility to make sure it's appropriate for the intended target)

> My friend explained to me, very vaguely, something like "mov al,byte[string+1]",
> but that gives me the "invalid effective address".

That's strange... works for me. The "byte" isn't necessary here - using "al" determines the size of the instruction (true for Masm, too).

The major differences between Masm and Nasm syntax are covered in section 2 of the Nasm manual. The most confusing situation (IMO) is with something like:

mov ax, foo

If that's Nasm syntax, it means what Masm would write as "mov ax, OFFSET foo". If it's Masm syntax, it means what Nasm would write as "mov ax, [foo]"... IF "foo" is defined as "foo dw 42" or something. If "foo" is "foo equ 42", then it stays the same in Nasm!

In Nasm syntax, all memory references are in square brackets, and all of the effective address must be within the brackets - Masm: "es:[si]", Nasm: "[es:si]", Masm "foo[bx]", Nasm "[foo + bx]", etc... as well as Masm: "foo", Nasm, "[foo]". Masm will let you get away with "inc foo" - you often see "inc word ptr foo", but Masm "remembers" what size you said "foo" was. Nasm does not, so you must specify the size "inc word [foo]" when the size isn't specified by the operand.

Anything *not* in square brackets is an "immediate", whether it's a variable name, a label, a literal number, or an expression that evaluates to a number... unless, of course, it's a register :)

Is that enough confusion for the time being? :)

Best,
Frank

nobody

  • Guest
Re: New to NASM syntax
« Reply #2 on: January 31, 2005, 08:30:49 PM »
Thanks frank, it turns out that using  CX was the problem. Which you told me.

But can you explain to me, some of the basic uses of the registers, so this doesn't happen again. And why I should, for instance, not use the cx register in this situation ?

Help greatly appreciated.

nobody

  • Guest
Re: New to NASM syntax
« Reply #3 on: January 31, 2005, 08:36:00 PM »
Sorry for posting right away, but didn't come up 'til I had posted.

Should the "times 510-($-$$) db 0" label be modified to get the binary file to exactly 512bytes? That is, should the number 510 be modified?