Nasm syntax problem

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
computertrick
Member
Member
Posts: 71
Joined: Wed May 29, 2013 1:07 pm

Nasm syntax problem

Post by computertrick »

Hi this is likely a noobie question but how come this code does not work

Code: Select all

TEST dd 0x00
TEST2 dd 0x00

mov dword[TEST], [TEST2]
 
Thats just a basic example. How come I can't move data directly why must it be put into registers first
1100110100010011
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

Re: Nasm syntax problem

Post by HugeCode »

Because x86 instructions can have only one displacement. The instruction set is designed so.
computertrick
Member
Member
Posts: 71
Joined: Wed May 29, 2013 1:07 pm

Re: Nasm syntax problem

Post by computertrick »

I'm trying not to write dirty code that's why I asked. Can anyone see anything in my code that should be done differently

Code: Select all

org 0 ; we start everything at zero
	jmp start     
MANU_DESC 			db 'mkdosfs '
BLOCK_SIZE	 		dw 512
BLOCKS_PER_ALLOCATION_UNIT 	db 128
RESERVED_BLOCKS			dw 1
TOTAL_FATS			db 1
TOTAL_ROOT_ENTRIES		dw 512
TOTAL_BLOCKS			dw 0xffff
MEDIA_DESCRIPTOR		db 0xf8
BLOCKS_PER_FAT			dw 0x01
BLOCKS_PER_TRACK		dw 18
TOTAL_HEADS			dw 0x02
HIDDEN_BLOCKS			dd 0x00
TOTAL_BLOCKS_2			dd 0x00
DRIVE_NUMBER			dw 0x00
EXTENDED_BOOT_SIGNATURE		db 0x29
VOLUME_SERIAL_NUMBER		dd 0x9d86f18c
VOLUME_LABEL			db 'SEAGULL    '
FILE_SYSTEM_IDENTIFIER		db 'FAT16   '

; Calculated in memory
ROOT_DIRECTORY		dd 0x00

DAPACK:
	db 0x10
	db 0
.len:	dw 1
.loc:	dd 0x7e00
.sec:	dd 2
	dd 0
	
start:

	mov ax, 0x7c0
	mov ds, ax
	mov es, ax
	mov sp, 0x1000
	mov bp, 0
	mov ss, bp


; Root Directory Logical Sector =  (TOTAL_FATS * BLOCKS_PER_FAT) + (RESERVED_BLOCKS)

	mov ax, [TOTAL_FATS]
	mul word [BLOCKS_PER_FAT]
	mov word [ROOT_DIRECTORY+2], dx
	push dx
	add ax, [RESERVED_BLOCKS]
	mov word [ROOT_DIRECTORY], ax


; Load root directory


	mov word [DAPACK.sec], ax
	pop dx
	mov word [DAPACK.sec+2], dx

	mov si, DAPACK		; address of "disk address packet"
	mov ah, 0x42		; AL is unused
	mov dl, 0x80		; drive number 0 (OR the drive # with 0x80)
	int 0x13
	jc err

	mov si, 512
	mov bx, 40
	call print_until

	jmp $

err:
	mov si, ERROR
	call print
	jmp $


print:
	pusha
	mov ah, 0eh
.repeat:
	lodsb
	cmp al, 0
	je .done
	int 10h
	jmp .repeat
.done:
	popa
	ret

print_until:
	mov ah, 0eh
.repeat:
	lodsb
	cmp bx, 0
	je .done
	int 10h
	dec bx
	jmp .repeat
.done:
	popa
	ret

ERROR db "Failed to load sector", 10, 13, 0
times 510-($-$$) db 0 ; fill in the remaining space with zero
dw 0xaa55 ; legacy boot signature
1100110100010011
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

Re: Nasm syntax problem

Post by HugeCode »

Are you getting some error output?
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: Nasm syntax problem

Post by Antti »

Code: Select all

start:
   mov ax, 0x7c0
   mov ds, ax
   mov es, ax
   mov sp, 0x1000
   mov bp, 0        ; <----- Critical point
   mov ss, bp
It is dangerous to change just the SP and let interrupts be enabled. There a couple of ways to solve this. Maybe this is most easiest to understand:

Code: Select all

start:
	jmp 0x7c0:update_cs
update_cs:

   mov ax, 0x7c0
   mov ds, ax
   mov es, ax
   cli
   mov sp, 0x1000
   mov bp, 0
   mov ss, bp
   sti
I also updated CS to be equal with ES and DS. I did not check more of your code.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Nasm syntax problem

Post by Combuster »

org 0
jmp start
MANU_DESC db 'mkdosfs '
How many bytes is a jump? 2? 3? 5? How many bytes should exist between the start of the sector and the OEM field? :wink:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
computertrick
Member
Member
Posts: 71
Joined: Wed May 29, 2013 1:07 pm

Re: Nasm syntax problem

Post by computertrick »

jmp start allocates 3 bytes this can't change or it will damage my FAT format
1100110100010011
Prochamber
Member
Member
Posts: 100
Joined: Wed Mar 13, 2013 2:27 am

Re: Nasm syntax problem

Post by Prochamber »

Here's the problem: Optimizations.
When the context is not specific and optimizations are enabled, NASM will try to generate the smallest and/or fastest instruction possible. The maximum level of optimization is enabled by default. Your initial jump must occupy three bytes or it will break the file system.

So, unless you disable optimizations or specify the length of your jump NASM will compile this as the smallest possible jump, which is a two byte jump. I recommend you either
a) Be more specific (recommended)

Code: Select all

jmp word start
OR

Code: Select all

jmp short start
nop
b) Assemble with the -O0 flag to disable optimizations.

By the way, if you want to do memory to memory moves, you could use the movs instruction. This copies a byte,
word or double word from DS:SI to ES:DI and increases both SI and DI if the carry flag is cleared. Otherwise they are decreased.
TachyonOS - Violates causality on 95% of attempts. Runs at approximately 1.5c.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Nasm syntax problem

Post by Combuster »

Or you can just make sure there's three bytes regardless of what your assembler tries.

Code: Select all

start:                  JMP loader
 
                        TIMES 0Bh-$+start DB 0
bpbBytesPerSector:  	 DW 512
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Minoto
Member
Member
Posts: 89
Joined: Thu May 12, 2011 7:24 pm

Re: Nasm syntax problem

Post by Minoto »

Prochamber wrote:By the way, if you want to do memory to memory moves, you could use the movs instruction. This copies a byte,
word or double word from DS:SI to ES:DI and increases both SI and DI if the carry flag is cleared. Otherwise they are decreased.
I believe you meant the direction flag, not the carry flag.
Those who understand Unix are doomed to copy it, poorly.
computertrick
Member
Member
Posts: 71
Joined: Wed May 29, 2013 1:07 pm

Re: Nasm syntax problem

Post by computertrick »

Prochamber wrote:Here's the problem: Optimizations.
When the context is not specific and optimizations are enabled, NASM will try to generate the smallest and/or fastest instruction possible. The maximum level of optimization is enabled by default. Your initial jump must occupy three bytes or it will break the file system.

So, unless you disable optimizations or specify the length of your jump NASM will compile this as the smallest possible jump, which is a two byte jump. I recommend you either
a) Be more specific (recommended)

Code: Select all

jmp word start
OR

Code: Select all

jmp short start
nop
b) Assemble with the -O0 flag to disable optimizations.

By the way, if you want to do memory to memory moves, you could use the movs instruction. This copies a byte,
word or double word from DS:SI to ES:DI and increases both SI and DI if the carry flag is cleared. Otherwise they are decreased.
Hi thanks for your response, When I look at the hex code the jump has allocated 3 bytes and the file system works fine
1100110100010011
Prochamber
Member
Member
Posts: 100
Joined: Wed Mar 13, 2013 2:27 am

Re: Nasm syntax problem

Post by Prochamber »

Are you sure? When I compiled your code with the latest version of NASM, ndisasm shows the first instruction being a two byte 'short' jump with no intervention. This is followed directly by the OEM identifier.

Code: Select all

00000000  EB4F              jmp short 0x51
TachyonOS - Violates causality on 95% of attempts. Runs at approximately 1.5c.
computertrick
Member
Member
Posts: 71
Joined: Wed May 29, 2013 1:07 pm

Re: Nasm syntax problem

Post by computertrick »

Prochamber wrote:Are you sure? When I compiled your code with the latest version of NASM, ndisasm shows the first instruction being a two byte 'short' jump with no intervention. This is followed directly by the OEM identifier.

Code: Select all

00000000  EB4F              jmp short 0x51
Yes I am sure because both windows and linux can recognize the file system and it runs fine in qemu. But I am not 100% sure I have the latest version of nasm so I will modify the JMP just to take precautions cheers for letting me know about that
1100110100010011
Prochamber
Member
Member
Posts: 100
Joined: Wed Mar 13, 2013 2:27 am

Re: Nasm syntax problem

Post by Prochamber »

If you have a version before 0.98 optimisations are not enabled by default, but they are for newer version.

There's not much more to improve, however you could use CX instead of BX to specify the number of bytes to print in "print_until" then you could use the Loop instruction to shave a few bytes off.

Code: Select all

print_until:
pusha
mov ah, 0Eh
.repeat:
lodsb
int 10h
loop .repeat
popa
ret
Your routine actually looses the stack because it uses popa without pusha.
You should clear interrupt before changing the stack pointer and segment then restore them afterwards.
TachyonOS - Violates causality on 95% of attempts. Runs at approximately 1.5c.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Nasm syntax problem

Post by gerryg400 »

You should clear interrupt before changing the stack pointer and segment then restore them afterwards.
It's not necessary to disable interrupts if the SS is loaded first. The processor does it for you automatically.
The Intel manual wrote:Loading the SS register with a MOV instruction inhibits all interrupts until after the execution of the next instruction. This operation allows a stack pointer to be loaded into the ESP register with the next instruction (MOV ESP, stack-pointer value) before an interrupt occurs1. Be aware that the LSS instruction offers a more efficient method of loading the SS and ESP registers.
If a trainstation is where trains stop, what is a workstation ?
Post Reply