Can I use both relative and absolute addressing for JMP/CALL or can I only use one?
Posted on 2004-01-31 20:05:45 by Maddox
Maddox,
Before any of us take a crack at answering you, why don't you explain either by code example or prose, what you mean by relative, direct, or indirect addressing. Then we will all be singing from the same song book. Ratch
Posted on 2004-01-31 21:07:20 by Ratch

Maddox,
Before any of us take a crack at answering you, why don't you explain either by code example or prose, what you mean by relative, direct, or indirect addressing. Then we will all be singing from the same song book. Ratch


If I want to jump to another memory address that is 20h bytes away do I JMP 20 or do I JMP 6F101230(example)? And does CALL work the same way?

The reason is when I look at assembly generated by w32dasm I have no idea if it puts the full address at jmps to make it easier to read or if that is really how it looks. Also in ASM source they use labels which causes the compiler to do those calculations for you.

Are we singing from the same book now?
Posted on 2004-01-31 21:52:33 by Maddox
e9 jump = take current va, add dword from va+1, add size of opcode = destination it will jump to, e8 works the same way, e9= long jump, eb = short jump (2 byte opcode, 1 byte = eb (jmp short), next byte is the amount it will change the eip by (if its <127 then its going forwards, greater than 127, its going backwards.. i think heh), you really need to look at it in opcode form to understand, w32dasm etc calculates the addresses for you and yes assembler does use labels, but those labels are only for the coder etc to understand the code easier, the assembler (not compiler then calculates the va's of the labels when its making the executable and updates the opcodes with the va's etc..
Posted on 2004-01-31 21:59:38 by evlncrn8
Maddox,
Well, lets talk just about jumps then. If you want to code a jump to an address 20 bytes forward of your present address, you code JMP $+20. If you code it JMP 20, MASM does not know if you want to jump to address 20 or 20 bytes forward, so it will tell you that you can only jump to a label. The JMP instruction hardware uses the operand to jump that number of bytes forward or backword, so the assembler has to figure out the signed displacement from the current address and stuff it into the instruction operand. If the displacement is more than what 16 bits can represent, then the assembler must select the 32-bit jump instruction. I know nothing about W32DASM, and this is a MASM form. Usually an assembler will output an object file which has addresses relative to the segments (.CODE, .DATA.,.DATA?, etc). Included with these displacements is relocation information which the linker uses to make absolute addresses for the exe file. Ratch
Posted on 2004-01-31 22:26:49 by Ratch

e9 jump = take current va, add dword from va+1, add size of opcode = destination it will jump to, e8 works the same way, e9= long jump, eb = short jump (2 byte opcode, 1 byte = eb (jmp short), next byte is the amount it will change the eip by (if its <127 then its going forwards, greater than 127, its going backwards.. i think heh), you really need to look at it in opcode form to understand, w32dasm etc calculates the addresses for you and yes assembler does use labels, but those labels are only for the coder etc to understand the code easier, the assembler (not compiler then calculates the va's of the labels when its making the executable and updates the opcodes with the va's etc..


Wow... one long sentence. Does w32dasm mess with the address in the opcode?
Posted on 2004-01-31 22:27:08 by Maddox
nope, rather w32dasm generates the address from the opcode, have a look at the opcodes and do the math using the info in my previous long sentence
Posted on 2004-01-31 22:30:03 by evlncrn8

Maddox,
Well, lets talk just about jumps then. If you want to code a jump to an address 20 bytes forward of your present address, you code JMP $+20. If you code it JMP 20, MASM does not know if you want to jump to address 20 or 20 bytes forward, so it will tell you that you can only jump to a label. The JMP instruction hardware uses the operand to jump that number of bytes forward or backword, so the assembler has to figure out the signed displacement from the current address and stuff it into the instruction operand. If the displacement is more than what 16 bits can represent, then the assembler must select the 32-bit jump instruction. I know nothing about W32DASM, and this is a MASM form. Usually an assembler will output an object file which has addresses relative to the segments (.CODE, .DATA.,.DATA?, etc). Included with these displacements is relocation information which the linker uses to make absolute addresses for the exe file. Ratch


And when you use CALL?
Posted on 2004-01-31 22:30:44 by Maddox
It is the same, just that there is no 8bit variation of call just the 32bit.
Posted on 2004-01-31 22:40:23 by roticv
Maddox,
And when you use CALL?

A CALL is used when you want the return address of the next instruction to be first PUSHed onto the stack. Then the CALL instruction does a JMP to the specified location. After the processing is finished at that location where a subroutine resides, a RET instruction is coded. This takes the top stack entry and uses it to JMP to where if came from. That is all explained in the x86 documentation. This is the last basic question I will answer. Ratch
Posted on 2004-01-31 22:52:14 by Ratch

Maddox,
Before any of us take a crack at answering you, why don't you explain either by code example or prose, what you mean by relative, direct, or indirect addressing. Then we will all be singing from the same song book. Ratch


What is there to explain? His question was crystal clear.
Posted on 2004-01-31 23:19:39 by comrade

If the displacement is more than what 16 bits can represent, then the assembler must select the 32-bit jump instruction.

Wrong. It's when the displacement cannot be expressed as a signed byte.

Also, it's worth mentioning that the displacement is calculated from the byte *after* the opcode - ie, if you're at adress 8 and doing "jmp $+10", this would be encoded "EB 00". If you're at address 10 doing "jmp 8", you get "EB FC". (Modulu-2 addition: (0x10 + 0x02) + 0xFC = 0x08).

Maddox, perhaps this answer is simpler. There's a number of different ways to do the CALL and JMP instructions. Of the simple ones, there's EB (direct jump, signed byte EIP-displacement), E9 (direct jump, signed dword EIP-displacement), E8 (direct call, signed dword EIP-displacement). FF25 (indirect jmp, absolute dword address), FF15 (indirect call, absolute dword address).

Note that indirect means just that - the CPU looks at the dword specified in the absolute address, specified by the opcode, fetches the dword address there, and calls/jmps to that location.

To complicate matters, there's scale+index+base forms (stuff like "call "), inter-segment jump/call, et cetera. And of course I'm assuming 32bit code, stuff looks a bit different in 16bit.
Posted on 2004-02-01 00:08:22 by f0dder
comrade,
What is there to explain? His question was crystal clear

Then why don't you take a turn at answering it? Ratch
Posted on 2004-02-01 01:19:37 by Ratch
f0dder,
Wrong. It's when the displacement cannot be expressed as a signed byte.

Yes, you are correct. The switchover occurs at the byte limit. Sorry for the confusion. Ratch
Posted on 2004-02-01 01:23:32 by Ratch
Thanks for the information guys, it is much appreciated.
Posted on 2004-02-01 01:50:23 by Maddox