Page 1 of 1

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

Posted: Wed Jul 11, 2018 4:27 am
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 ?

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

Posted: Wed Jul 11, 2018 4:31 am
by alexfru
You can't push/pop a byte.

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

Posted: Wed Jul 11, 2018 4:56 am
by bobgimax
Oh difficulty sometimes hide in simple problems #-o Thank you !

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

Posted: Wed Jul 11, 2018 5:28 am
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.