iret and ret ?

Programming, for all ages and all languages.
Post Reply
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

iret and ret ?

Post by Sam111 »

I have read this
The difference between IRET and RET is that IRET pops an extra 2 bytes off the stack (the flags register is popped). An interrupt call always pushes the flags onto the stack before pushing on the far return address. In general, hardware interrupt handlers use an IRET statement while software interrupt handlers use a RETF 2 (far return) statement
I have made a utility.asm file which looks like this

Code: Select all


set_graphics_mode:
mov ah , 00h
int 10h
pop ax
ret

....etc
And I am calling it in my other asm files
by

Code: Select all

mov ax , 00h
push ax
call set_graphics_mode

but I my questioning should I use iret in the utility.asm functions if I am using an interrupt or just the regular ret.

Basically is the iret only used at the end of your homemade interrupt or irq function or when a function is calling an interrupt and returning to the callee.

I know from the above quote iret pops the extra flags register on the stack. But apart from that I don't see if their is any other difference between iret and ret...?

As well when you call int 10h or something what gets pushed on the stack just the flags register?
Or could you do the equivalent of an int 10h call by
pushing the flags register eflags onto the stack
and doing a jump to the int 10 interrupt address in the IVT.
Curious?
Thanks for any help
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: iret and ret ?

Post by Gigasoft »

When you cause a software interrupt, the flags register is pushed followed by CS and IP. The iret instruction does the reverse, it pops IP, CS and then the flags register. Yes, you can invoke an interrupt by doing a pushf and then (assuming that DS is set to 0 and you want to invoke int 10h) call far word ptr ds:[40h]. Only the lower 16 bits of the flags are pushed when in real mode.

Only interrupt handlers should return using iret. Normal procedures such as set_graphics_mode should use ret if they are called with a regular call, and retf if they are called using a call far instruction. I don't know what you're trying to accomplish with the push ax and pop ax, but it definitely won't work.

If you want to use a parameter that was passed on the stack as the graphics mode, the function should be written in one of the following ways:

Code: Select all

set_graphics_mode:
push bp
mov bp,sp
movzx ax,byte ptr [bp+4]
int 10h
pop bp
ret 2
Or:

Code: Select all

set_graphics_mode:
pop cx
pop ax
push cx
mov ah,0
int 10h
ret
If you just want to pass the parameter in AL and not on the stack, the code would be:

Code: Select all

set_graphics_mode:
mov ah,0
int 10h
ret
There is one additional difference between retf and iret. If NMIs are masked, iret unmasks them. In protected mode however, interrupts and iret work in a completely different way.
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: iret and ret ?

Post by Love4Boobies »

Sam111 wrote: I have made a utility.asm file which looks like this

Code: Select all


set_graphics_mode:
mov ah , 00h
int 10h
pop ax
ret

....etc
And I am calling it in my other asm files
by

Code: Select all

mov ax , 00h
push ax
call set_graphics_mode

There are only disadvantages to what you're doing:
  • Extra overhead (you access the stack for the argument, return addresses and the actual call) - as if the BIOS wasn't slow enough.
  • It's not convenient in any way. You have overhead at the cost of writing one extra line in your source code (mov, push, call vs. mov, int).
  • You need a slightly bigger stack.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: iret and ret ?

Post by Sam111 »

OK , I am just curious on why this won't work?

Code: Select all

read_character_and_attribute:
push bx 
push cx
push dx
mov ah , 08h
int 10h
pop dx
pop cx
pop bx
ret
basically I pushed the variables bx , cx , and dx onto the stack to safe their values call the int 10h then pop all the dx , cx , and bx values back into the dx , cx ,and bx registers and return to the callee.

What is wrong about that?

When you use the call instruction does it push anything on the stack before it goes to the function.
If so can a call instruction be translated into an equivalant jmp instruction with a few push instruction or something? (I would think the call instruction only pushes the return address on the stack but I could be
forgetting something.)

And ret just jumps back to the return address and pops it off the stack though I don't know in what order...?
So I would think ret could be translated into an equivalant jmp to return address and pop return address of the stack (i.e a jmp command and a pop command) ???

Curious if this is the same as ret

Code: Select all


jmp sp  <--return_address
pop sp

or for 32bits

jmp esp <---return_address
pop esp


Thanks
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Re: iret and ret ?

Post by bewing »

Call =

Code: Select all

	PUSH EIP
	JMP $FUNCTION
Ret effectively pops the old EIP off the stack into a hidden register, then does a JMP to the value in that hidden register (so you have the order backwards above).

And to answer your original question: using interrupts is very very slow. In Pmode, it is one of only 3 ways to handle "privilege level switching" -- from usermode to kernelmode, so you may be FORCED to use it because you have no other real choice. If you are not in Pmode, then it is always better to use CALL/RET rather than INT/IRET for writing functions.

And your code example above should work fine. It does just what you say. That INT 10h function may also trash the value in AX -- if you care about any other registers than BX, CX, DX, then you need to look at RBIL and see which registers get overwritten with new values.
Last edited by bewing on Tue Apr 06, 2010 9:22 am, edited 1 time in total.
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: iret and ret ?

Post by Gigasoft »

OK , I am just curious on why this won't work?
It should work, assuming that the registers were set correctly.
Curious if this is the same as ret
No. That would jump to the current value of ESP, and interpret the contents of the stack as instructions. And instructions that are placed after a jump instruction aren't executed. The following performs the same function as ret, but overwrites cx:

Code: Select all

pop cx
jmp cx
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: iret and ret ?

Post by Sam111 »

Ok , I see
But the first person that posted gave this

Code: Select all

If you want to use a parameter that was passed on the stack as the graphics mode, the function should be written in one of the following ways:

Code:
set_graphics_mode:
push bp
mov bp,sp
movzx ax,byte ptr [bp+4]
int 10h
pop bp
ret 2



Or:

Code:
set_graphics_mode:
pop cx
pop ax
push cx
mov ah,0
int 10h
ret



If you just want to pass the parameter in AL and not on the stack, the code would be:


I am wondering about the first set_graphics_mode as well as the second one.
In the second one why does he do 2 pops and a push instruction ?


Also this statement
And to answer your original question: using interrupts is very very slow. In Pmode, it is one of only 3 ways to handle "privilege level switching" -- from usermode to kernelmode, so you may be FORCED to use it because you have no other real choice. If you are not in Pmode, then it is always better to use CALL/RET rather than INT/IRET for writing functions.
well I am in 16bit mode and if I want to set a graphics screen resolution I would need to use an int command.
I am curious though why int /IRETcommands is much slower then the call/ret commands.

I thought the int command just pushed an addition flags registar on the stack as opposed to just pushing the cs ip registers on the stack....etc
So it would only be one more thing it does more then the call command . Correct me if I am wrong.

Also correct me if I am wrong
when the computer first starts up the only thing we have availible function wise is the bios interrupts and the VGA/VESA graphics interrupts (i.e int 13h , int 10h )

Is their any other interrupts that are universial (i.e you can pretty much count on them to be availble at bootup)
I know their is a list of interrupts ,...etc here http://www.ctyme.com/intr/int.htm
and many other places but I am not sure how univerial they are for a particular computer .

can you count on keyboard interrupts int 16h , mouse , sound ,...etc as well.
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: iret and ret ?

Post by Gigasoft »

Code: Select all

set_graphics_mode:
pop cx
pop ax
push cx
mov ah,0
int 10h
ret
First, the return address is popped. Then the parameter is popped into ax to be used with the int 10h. Then the return address is pushed again, so that the ret will use it.

At startup, you can only count on standard BIOS interrupts (10h through 1ah).

The discussion about speed is only relevant for code that executes many times repeatedly (for example, it would be a bad idea speedwise to use the BIOS set pixel service in a loop to fill a rectangle).
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: iret and ret ?

Post by Sam111 »

The discussion about speed is only relevant for code that executes many times repeatedly (for example, it would be a bad idea speedwise to use the BIOS set pixel service in a loop to fill a rectangle).
gotcha on all that.
When I was in text mode I used the MMIO at 0xB8000 and every even array element /memory address corrosponded to the value and the odd address corosponded to the attribute (background color etc..)

But now I put my monitor in graphics mode

Code: Select all

06   Graphics       2      80x25   640x200        1       B8000h
I am wondering how to set a given pixel in protected mode since I have switch from real to protected 32bit mode. I am wondering if their is an equivalent MMIO for graphics mode???

Also is their any high resolution for text mode or is it just
80 by 25 or 40 by 25 because it would be nice to have really small texted maybe the only way is to do it in graphics mode....

Also when would you use MMIO at A0000h instead of B8000h ?

Thanks for your help
gotcha on the pop stuff as well .
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: iret and ret ?

Post by Gigasoft »

All BIOS non-CGA graphics modes use addresses 0xA0000 through 0xAFFFF to access the screen.

The screen in mode 6 is accessed at 0xB8000. Each line is 80 bytes long, and each byte represents 8 pixels where the MSB is the leftmost pixel. Even numbered lines are accessed at 0xB8000 and odd numbered lines at 0xBA000. Mode 6 is obsolete, and I recommend mode 12h instead. In mode 12h, every line occupies 80 consecutive addresses and the lines are stored sequentially. The screen is accessed at 0xA0000. Each of the 4 bits of the color index is stored in its own plane. Graphics register 8 selects the color planes to write to. For example, if the color plane number is stored in CL, this code will select it for writing:

Code: Select all

mov ah,1
shl ah,cl
mov al,8
mov dx,3ceh
out dx,ax
Mode 13h is easier to use. Here, the screen is accessed at 0xA0000 and the lines are stored sequentially. Each byte contains two nibbles which are translated according to the attribute palette registers and concatenated to form an 8-bit palette index.

The following will change the number of rows in text mode to 50:

Code: Select all

mov bl,0
mov ax,1112h
int 10h
To have 44 rows, you would use the code above followed by:

Code: Select all

mov dx,3d4h
mov ax,4809h
out dx,ax
mov ax,8b12h
out dx,ax
High resolution text modes can be programmed, but aren't part of the standard BIOS mode set. Some BIOSes offer them as VESA modes.
johng
Posts: 1
Joined: Sat Dec 15, 2012 6:33 am

Re: iret and ret ?

Post by johng »

please people, the only reason you use a 'ret' (00CBh) is to return to a caller sub-routine. if your subroutine uses an interrupt 'INT XX' then the next command on return from the interrupt is the next command only, as i say 'unless you 'accessed' the sub-routine containing the interrupt from another sub-routine containing the 'call' (00E8h) command. the 'call' and 'ret' command go hand-in-hand. now, unless you are going to be writing your own "interrupt" routines a task i don't suggest anyone try without at least five years professional experience and a command by command knowlege of the entire bios of the computer that you are using, you have NO need of understanding of the workings of the 'IRET' command as this command is used most commonly by the bios to return control, by and from, the internal system, from the internal workings of a bios only routine to the subroutine that you have written. look, for those of you who ARE more than a little curious about how GRANPA IBM does things, there are, or were, a couple of really engrossing publications available on specifically this subject,... they are The DOS 5 Bible by Steven Simrin, and, Assembly Language TUTOR by Richard E. Haskell, upon acquiring a copy of both these thomes you may consider yourself in a 'real' position if you are on Windows to navigate to C:\Windows\system32\cmd.exe, put a shortcut for cmd.exe to the desktop, double-click on it, the whilst DOS is coming up, turn to the section on 'DEBUG' in the DOS 5 Bible, then once DOS is on screen type 'debug' then start straining that grey-matter until it creaks.... all the best, johng
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: iret and ret ?

Post by bluemoon »

Please check the date before putting a reply :) This thread dead 2 years ago. :shock:
johng wrote:i don't suggest anyone try without at least five years professional experience and a command by command knowlege of the entire bios of the computer that you are using, you have NO need of understanding of the workings of the 'IRET' command as this command is used most commonly by the bios to return control, by and from, the internal system, from the internal workings of a bios only routine to the subroutine that you have written.
IRET is pretty much essential for OS development (look at the domain name of this forum), and it's not exclusive for BIOS.
Post Reply