Skip to main content
GameDev.net gamedev.net
🔒 Locked

Assembler jump function

Started by RamboBones Dec 15, 2002 at 9:56 PM 7 replies 250+ views
Original Post
RamboBones
RamboBones
I''m learning assembler and I''m trying to understand the jmp funciton. I can understand this jmp address but I don''t get this jmp add1:add2 what does that do. I know the first one jumps within the current segment, what''s that? and the second one sets a new segement but what are segments and exactly where does the second jmp funtion jump to and what does it do
Gladiator
Gladiator
Segment:offset is used in a 16-bit environment. The reason you use that is because you can only use 16-bit variables, which can have a value between 0 and 65535.

Now, if you have 4GB worth of memory, you cannot have a single variable represent a pointer to memory, since the farthest that pointer can reach is 65535, which is 64KB. Now, if you use two 16-bit values to make up a virtual 32-bit pointer, we are in business. So they way it works is, you have segment:offset, two 16-bit unsigned integers represent an effective memory address. You use them like a 2D array.

Here's some code to show you how memory with segment:offset works.

Let's say memory is defined like this:

byte memory[0xFFFF][0xFFFF];

Now, let's say we want to access mode 13h and draw some stuff. In C code we do this as follows:

memory[0xA000][0x0000] = 0;

In this case segment = 0xA000 and offset = 0x0000.

Now let's say we are in a 32-bit environment and we can have a continues memory, in which case we don't use segment:offset, we will have memory defined as follows:

byte memory[0xFFFF*0xFFFF];

Now in order to access the same element from the previous example with segment:offset memory addressing, we would do the following:

memory[0xA000*0xFFFF + 0x0000] = 0;

This is the principle that windows uses, since it's a 32-bit operating system.

Where as DOS uses something similar to our previous example, with segmentation and offsets.

Hope this helps you understand the basic idea of the segment:offset concept. It's late and I'm tired so I might have missed something on the way.

Let me know if you have any questions.

[edited by - Gladiator on December 16, 2002 3:21:24 AM]
rotos
rotos
This is only important when doing 16-bit stuff, in 32-bit 'jmp address' will handle all your needs.

Anyway, an explaination,

A segment is an area of memory. The segment registers (I forgot their names, so bear with me) each hold a 16 bit value. In 16-bit mode, every memory access takes a value from the appropriate segment register, shifts it left by four, then adds the 16-bit address given by the instruction and uses that as the effective address for the instruction.

For example, to accese 0xA0000, the VGA frame-buffer, you would first load a segment regitser with 0xA000, then use
mov segmentregister:address to access the memory. 0xA000 << 4 + 0 = 0xA0000.

The jmp instruction you've shown, simply loads the upper word into the code segment register, then sets the program to start at the address in the segment specified by the second word.

[edited by - rotos on December 16, 2002 3:37:40 AM]
JuNC
JuNC
In any protected mode, segments can still be used (indeed are required but you can ignore them in some instances) need not map directly to memory in the way they do in real mode. The jmp seg:addr is still valid in 32bit protected mode but doesn''t work in quite the same way (it can be trapped by the hardware/OS).
Jan Wassenberg
Jan Wassenberg
Small note: every x86 has segmentation enabled – no way around it. Normal memory access goes through ds (data segment), while instructions like scasd use the es (extra segment); finally, cs (code segment) and ss (stack segment) are as advertised.
What modern 32 bit flat mode OSes do is make each segment 4 GB, and prevent the app from messing with the segment regs (that hides segmentation as much as possible from the app). Also, instead of the simple EA = (segment << 4) + offset calculation in real mode, protected mode segments have a fixed base address (stored in a table), which is added to all accesses to that segment.
Now what jmp seg:ofs does is the same in real and pmode: load seg into cs (in pmode, it’ll be a selector, i.e. index into the segment descriptor table), and then jump to ofs within the segment.
The only time you should need to do this, BTW, is when booting an OS.

HTH
Jan

HTTP 500 strike 1...
E8 17 00 42 CE DC D2 DC E4 EA C4 40 CA DA C2 D8 CC 40 CA D0 E8 40E0 CA CA 96 5B B0 16 50 D7 D4 02 B2 02 86 E2 CD 21 58 48 79 F2 C3
RamboBones
RamboBones
[qote]
The only time you should need to do this, BTW, is when booting an OS.


That''s exactly what I''m trying to do
Jan Wassenberg
Jan Wassenberg
Hehe

In that case, you can use int 15, 0x89 to switch to pmode (which is what I did, seeing as everything had to fit in the boot sector).
If you wanna do it by hand, here’s what you do: CODE is segment selector for a privileged (since this’ll be what your OS init code runs in), and probably 4 GB / base = 0, segment. Selector is just the offset of the segment’s descriptor (8 bytes) in the descriptor table; note that the first descriptor can’t be used as such – I put the GDTR stuff in there. You’ll also need to know the offset (=: ofs) within CODE where execution is to continue.
And after all that talk, it boils down to jmp dword CODE:ofs

If you want a better explanation, read Intel’s System Programming book (volume 3).

/* edit: seg -> CODE */

[edited by - Jan Wassenberg on December 17, 2002 9:26:08 AM]
E8 17 00 42 CE DC D2 DC E4 EA C4 40 CA DA C2 D8 CC 40 CA D0 E8 40E0 CA CA 96 5B B0 16 50 D7 D4 02 B2 02 86 E2 CD 21 58 48 79 F2 C3
RamboBones
RamboBones
Thanks guys. That''s great stuff.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.