GNU AS : "push" and "pop" instructions not supported !

Programming, for all ages and all languages.
Post Reply
bobgimax
Posts: 10
Joined: Sun Jan 29, 2017 2:36 pm

GNU AS : "push" and "pop" instructions not supported !

Post by bobgimax »

Hello,

I'm currently writing a MBR, it contains a function to copy some sectors of the disk to the RAM and I decided to pass the parameters to this function by pushing them onto the stack but when I

Code: Select all

as -o mbr.elf mbr.s
GAS says that "push" (and "pop") instructions are not supported !
I can't figure out why they are not supported and how to fix this, can you help me ?
Here is the code of the MBR :

Code: Select all


	.code16	/* CPU is in 16 bits real mode */

start:	
	/* MBR code is loaded at 0x7C00 by the BIOS */
	mov $0x07C0, %ax
	mov %ax, %ds
	/* Stack grows downward from 0x80000 */
	mov $0x8000, %ax
	mov %ax, %ss
	mov $0x00, %sp
	
	movb %dl, (drive) /* Save drive number */

	/* Copy second sector to 0x500 */
	push %dl	/* Drive number */
	mov $0x01, %al	
	push %al	/* Copy 1 sector */
	mov $0x0500, %ax
	push %ax	/* Copy to 0x500 */
	mov $0x02, %al
	push %al	/* Sector 2 */
	mov $0x00, %al
	push %al	/* Head 0 */
	push %al	/* Cylinder 0 */
	call copy

end:
	jmp end
/* ----------------------- Copy function --------------------------

	Copies some sectors to RAM. Push arguments on stack
	in this order:
	+ Drive number (byte)
	+ Number of sectors to copy (byte)
	+ Address of copy (word)
	+ First sector CHS address as :
		- Sector (byte)
		- Head (byte)
		- Cylinder (byte)
	
------------------------------------------------------------------- */
copy:
	pop %al		/* Cylinder */
	mov %al, %ch
	and $0xFF, %ch

	pop %dh		/* Head */

	shr 2, %al
	and $0xC0, %al
	pop %cl		/* Sector */
	or %al, %cl

	pop %ax		/* Address */
	mov %ax, %bx
	shr 4, %ax
	sub %ax, %bx
	mov %ax, %es

	pop %al		/* Number of sectors */
	pop %dl		/* Drive number */

	mov $0x02, %al
	int $0x13
	
	ret

drive:
	.byte 0x00
	
	/* Code space padding */
	.skip 446 - (. - start), 0x90

	/* Partition table */
	.skip 0x40, 0x00

	/* Signature */
	.byte 0x55, 0xAA

Thanks in advance !

PS: Is this the proper way to pass parameters to a function ?
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: GNU AS : "push" and "pop" instructions not supported !

Post by alexfru »

You can't push/pop a byte.
bobgimax
Posts: 10
Joined: Sun Jan 29, 2017 2:36 pm

Re: GNU AS : "push" and "pop" instructions not supported !

Post by bobgimax »

Oh difficulty sometimes hide in simple problems #-o Thank you !
User avatar
Velko
Member
Member
Posts: 153
Joined: Fri Oct 03, 2008 4:13 am
Location: Ogre, Latvia, EU

Re: GNU AS : "push" and "pop" instructions not supported !

Post by Velko »

PS: Is this the proper way to pass parameters to a function ?
The way you're passing the parameters is fine. The way, you're retrieving them (inside the function) is not.

Call instruction pushes the return address on the stack. The proper (cdecl conforming) way would be something like:

Code: Select all

copy:
    push %bp
    mov %sp, bp

    mov 4(%bp), %ax
    mov 6(%bp), %dx

    /* do something with the values */

    pop %bp
    ret
Note: untested, I may have mixed up the parameter sequence, but the main idea is there.
If something looks overcomplicated, most likely it is.
Post Reply