News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How does Jmp and call really work?

Started by AgentSmithers, July 10, 2009, 09:44:02 PM

Previous topic - Next topic

AgentSmithers

Ive noticed that jmp short is followed by a hex value that tells it how many bytes to jump over to get to the dest, How does call work? I see call F5FFFFFF how does the processor know where to go in code, I can tell that F5FFFFFF is not a actual address, Perhaps a Mathematical express?

Slugsnack

call can have various starting bytes for calling near/far, relative/displacement to next instruction, absolute indirect, absolute/address like it says in opcodes.hlp..

it can start with :
e8, ff, 9a..

then the rest of the bytes encode the displacement/address. but i'm sure intel has more documentation on the exact encoding, most people have no interest in that though lol. i'll confess the only time i got interested in how instructions were encoded was to write a hook function. but judging by your.. 'interests' you've likely gone down that path already. not that it's much my business but i'd advise you stop trying to be a 'hacker' and do legitimate programming. in the long run it won't get you anywhere

anyway if you're really, really interested.. for like a 'formula' or something or how its encoded then like i said, either documentation or you can take a look at the source of a disassembler or assembler

dedndave

#2
i don't think F5 FF is a call - maybe a register call like "call [ebp-1]" or something like that

relative calls (E8) work like you said - it is relative to the address of the following instruction
direct calls and jumps go directly to the address specified in the operand
indirect calls specify an address of data that contains the branch address

AgentSmithers

Interesting. Thanks... Yeah I was trying to figure out F5FFFFFF

Perhaps its being pushed backwards?

dedndave

it looks like an operand with the opcode missing - just a guess

Farabi

Quote from: AgentSmithers on July 11, 2009, 12:18:26 AM
Interesting. Thanks... Yeah I was trying to figure out F5FFFFFF

Perhaps its being pushed backwards?

Judge from it look like call F5FFFFFF is calling a function at minus address, which mean, IP subsract with the value.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

Big Duke 6

Hmmmm, this is an interesting topic. Obviously I am getting old, as MASM does seem to be highly automated, and relies heavily on on the Win OS itself, and not so much as the processor, or hard coded routines.

I do not know how our PC's deal with JMP, s or JSR's (Call), but on everything else I have ever worked with, it was always the same. A JMP instruction places the destination address into the PC (Program Counter). When a Call/JSR is executed, the destination addy is placed into the PC, and places the address of the next line of executable code onto the Stack so that when an RET, or an END Op Code was encountered, the return addy was taken from the Stack, and placed into the PC (program counter).

dedndave

that is pretty much the case for x86 code, as well
but, there are a variety of ways JMP's and CALL's may obtain the destination address

        jmp     label
        jmp     eax
        jmp     [eax]
        jmp     [label]
        jmp     [label+eax]

for JMP and CALL, there are a few more register/offset variations, as well
conditional branches are limited to label addresses
but, there are 15 or 16 conditional branches to choose from

Big Duke 6

Quote from: dedndave on July 12, 2009, 05:54:08 PM
that is pretty much the case for x86 code, as well
but, there are a variety of ways JMP's and CALL's may obtain the destination address

        jmp     label
        jmp     eax
        jmp     [eax]
        jmp     [label]
        jmp     [label+eax]

for JMP and CALL, there are a few more register/offset variations, as well
conditional branches are limited to label addresses
but, there are 15 or 16 conditional branches to choose from
Well, I must not be as old as I thought... Thanks fer the heads up, dedndave!

I tried my best to answer the question without going into offset addressing, or the myriad other ways of how the next address to be executed can be placed into the PC.

May I assume that Conditional Branches still rely on the 'Math Register' to see if the condition is met? Uh, does CNZV still hold true for MASM32 programming in Windows?

To think that I have actually seen a functioning Imsai. Been a while since those daze it has...

dedndave

well - we call it a "flags" register - it is 32 bits wide - lol
besides the math flags, there are other control and indicator flags and some unused bits also
for math, there is overflow, carry, auxiliary carry, zero, and sign (i think that's all of em - that is without looking it up - lol)
auxliary carry - you can pretty much ignore that one - it is used primarily for packed BCD operations

you may want to browse through this tutorial a bit
http://website.masm32.com/iczelion/iczelion.zip

this is Ray's FPU tutorial
http://www.ray.masmcode.com/tutorial/index.html

you will also want to d/l these (intel software reference manual - 5 parts)...
http://www.intel.com/Assets/PDF/manual/253665.pdf
http://www.intel.com/Assets/PDF/manual/253666.pdf
http://www.intel.com/Assets/PDF/manual/253667.pdf
http://www.intel.com/Assets/PDF/manual/253668.pdf
http://www.intel.com/Assets/PDF/manual/253669.pdf

this is also handy...
http://www.intel.com/Assets/PDF/manual/248966.pdf

Big Duke 6

Thank you again, dedndave. Got 'em all.

Why all of a sudden, do I feel like Dr. Evil? ::)

dedndave

lol
well - truthfully, i haven't learned all the stuff in that material myself
i did some mainframe programming long ago
i learned assember with the 4004 and 8008
with the 8086/8088, i would say i was quite proficient
the pentiums have extended that instruction set quite a bit - this is where i need work
you may be overwhelmed at first
just stick with it - start simple and build on it
oh - and the masm32\examples folder will show you a bit of a variety of good info, as well
also - masm32\help - all of em are good - hlhelp is a good one to learn your way around the masm32 library
in that folder, opcodes will get you going on the instruction set

AgentSmithers

#12
Yes I do like to point out that their are two different types when it comes to calls and Jumps, One is Static Addressing where the compiler adds it to the exe during run time and the other is Dynamic addressing just like the difference between OFFSET and ADDR, Offset will staticly input the address because it exist during run time and the other one will use EPB+X to dynamically locate the information at runtime, the difference comes in between the two depending on how the code will be ran, for example a simple WriteMemory API with windows you can write Hexcode directly into a program and CreateRemoteThread to start it, This is used for LEGITMATE reasons cause Norton does the same to check for Viruses and scan the programs API checking for Socket connections before it even happens, Now when the code is executed obviously calls with Static addresses cannot be executed where Jmps in should I say Hex code can be, I just found this to be an interesting topic, and it gets us down and dirty with a close look at the x86 =)

Near Call -- Procedure Call (call)

    call   disp32
    call   *r/m32

        Operation

          near call rel{16|32}
          near call r/m{16|32}

        Description

    The call instruction calls near procedures using a full pointer. call causes the procedure named in the operand to be executed. When the called procedure completes, execution flow resumes at the instruction following the call instruction (see the return instruction).

    call rel{16|32} adds a signed offset to address of the instruction following the call instruction to determine the destination; that is, the displacement is relative to the next instruction. The displacement value is stored in the EIP register. For rel16, the upper 16 bits of EIP are cleared to zero resulting in an offset value that does not exceed 16 bits.

    call r/m{16|32} specifies a register or memory location from which the absolute segment offset is fetched. The offset of the instruction following the call instruction is pushed onto the stack. After the procedure completes, the offset is popped by a near ret instruction within the procedure.

    Both forms of the call instruction have no affect on the CS register.

        Example

    Program counter minus 0x11111111.

    call .-0x11111111
    Add a signed offset value to the address of the next instruction.

    call *4(%edi)

1. 0xE8: CALL rel32 - Call near, relative, displacement
2. 0xFF /2: CALL r/m32 - Call near, absolute indirect, address in r/m32
3. 0x9A: CALL ptr16:32 - Call far, absolute, address in operand
4. 0xFF /3: CALL m16:32 - Call far, absolute indirect address in m16:32




.386
option casemap:none
include \masm32\include\masm32rt.inc

        .code 
            start:
            xor eax, eax
            MyCallFunc:
            xor eax, eax
            call MyCallFunc
            jmp MyCallFunc
            call MyCallFunc
            jmp MyCallFunc
            call MyCallFunc
            jmp MyCallFunc
            ret
            end start
           


Translates to :

00401000 > $ 33C0           XOR EAX,EAX
00401002   $ 33C0           XOR EAX,EAX
00401004   . E8 F9FFFFFF    CALL main.00401002
00401009   .^EB F7          JMP SHORT main.00401002
0040100B   . E8 F2FFFFFF    CALL main.00401002
00401010   .^EB F0          JMP SHORT main.00401002
00401012   . E8 EBFFFFFF    CALL main.00401002
00401017   .^EB E9          JMP SHORT main.00401002
00401019   . C3             RETN


Looks like Call actuly does not use static addressing like I thought, It uses a Offset calculation from EIP probley to tell it where to move UP or DOWN.

.386
option casemap:none
include \masm32\include\masm32rt.inc

        .code 
            start:
            xor eax, eax
            MyCallFunc:
            xor eax, eax
            call MyCallFunc
            jmp MyCallFunc
            call MyCallFunc
            jmp MyCallFunc
            call MyCallFunc
            jmp MyCallFunc
            call MyCallFunc
            jmp MyCallFunc
            call MyCallFunc
            jmp MyCallFunc
            call MyCallFunc
            jmp MyCallFunc

            call MyPositiveJump
            jmp MyPositiveJump
            call MyPositiveJump
            jmp MyPositiveJump
            call MyPositiveJump
            jmp MyPositiveJump
            call MyPositiveJump
            jmp MyPositiveJump
            call MyPositiveJump
            jmp MyPositiveJump
            call MyPositiveJump
            jmp MyPositiveJump


            MyPositiveJump:
            ret
            end start


00401000 > $ 33C0           XOR EAX,EAX
00401002   $ 33C0           XOR EAX,EAX
00401004   . E8 F9FFFFFF    CALL main.00401002
00401009   .^EB F7          JMP SHORT main.00401002
0040100B   . E8 F2FFFFFF    CALL main.00401002
00401010   .^EB F0          JMP SHORT main.00401002
00401012   . E8 EBFFFFFF    CALL main.00401002
00401017   .^EB E9          JMP SHORT main.00401002
00401019   . E8 E4FFFFFF    CALL main.00401002
0040101E   .^EB E2          JMP SHORT main.00401002
00401020   . E8 DDFFFFFF    CALL main.00401002
00401025   .^EB DB          JMP SHORT main.00401002
00401027   . E8 D6FFFFFF    CALL main.00401002
0040102C   .^EB D4          JMP SHORT main.00401002
0040102E   . E8 25000000    CALL main.00401058
00401033   . EB 23          JMP SHORT main.00401058
00401035   . E8 1E000000    CALL main.00401058
0040103A   . EB 1C          JMP SHORT main.00401058
0040103C   . E8 17000000    CALL main.00401058
00401041   . EB 15          JMP SHORT main.00401058
00401043   . E8 10000000    CALL main.00401058
00401048   . EB 0E          JMP SHORT main.00401058
0040104A   . E8 09000000    CALL main.00401058
0040104F   . EB 07          JMP SHORT main.00401058
00401051   . E8 02000000    CALL main.00401058
00401056   . EB 00          JMP SHORT main.00401058
00401058   $ C3             RETN


And as you can see JMP is the same and Adds the Value to EIP then INC's it +1 to the value.. and of couse Jmp short uses a 1byte value so I belive it can only jump up to 127 + 1 bytes away, allowing Jmp to use a Negitive number to allow it to jump UP the code. Call being able to jump with 4bytes of a Signed offset but also pushing the Present EIP onto the Stack.