I'm programming in VB.net and i'm looking at the assembly language during debug...I see a line "call DWORD PTR DS [some hex]". What exactly does that hex represent?
Printable View
I'm programming in VB.net and i'm looking at the assembly language during debug...I see a line "call DWORD PTR DS [some hex]". What exactly does that hex represent?
the memory address where the function/sub being called resides.
-tg
errrrmmmm....assembly language in vb.net ? How do you get that because vb.net uses .NET not native x86 assembly. The code you have is in native x86 assembly.
.Net produces Intermediate Language (IL) which looks a lot like ASM, but its not.
IL is converted to machine code at runtime by the JIT compiler. This is what makes it cross-platform.
so techgnome says it's the memory address where the function/sub resides, but I checked it, by using the "memory" debug window(in vb.net) and the bytes that are located in that memory don't match the bytes that make up the assembly codes. When I load API functions, is the memory address that they are loaded the same as the one being "CALL ....[HEX]"? When I do a "dumpbin /EXPORTS" on a dll, i see addresses of the functions. Aren't these addresses where they are loaded? When "loadlibrary()" is called, something is loaded at these specific addresses; however they are not the same as the address in "CALL ... [hex]"
to make myself clearer, this is what i mean. Here's an "assembly" code I got from vb.net.
call dword ptr ds:[00835A08h]
but the location of the function is 0x039001C8. I'm sure of this location because it matches the bytes that represent the "assembly" code.
wossname - but call dword ptr ds:[00835A08h]is using the DS segment - IL doesn't use x86 segments!!!??/
call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms] - this is MSIL not x86
benmartin - are using some sort of obfuscator? or is it mixed language with c++?
I know its MSIL thats what I said. I said its NOT asm.
The JIT converts it into machine code at runtime (machine code != ASM). The dissasembly code that you see in the IDE is dependant on whether you are building DEBUG or RELEASE CODE. If its DEBUG then you are seeing IL code, if its release then I think its a dissassembled x86 version that came out of the JIT.
The JIT is an extra stage in the execution process.
Yeah- I know that - I'm was awfully confused sorry - because I've not used the vb.net debugger much and not read all the posts thoroughly. I thought benmartin magically got x86 assembly from compiling code in vb.net :P
This is something to do with the weird .NET interop (I call it weird because Im 100% sure how it works and I don't like .NET) - it probably calls some interop routine before calling the real library function. I.e. MyCode ->Call DLLInteropCode->Call Real DLLQuote:
to make myself clearer, this is what i mean. Here's an "assembly" code I got from vb.net.
call dword ptr ds:[00835A08h]
but the location of the function is 0x039001C8. I'm sure of this location because it matches the bytes that represent the "assembly" code.
If i interpreted it right.....Quote:
If its DEBUG then you are seeing IL code, if its release then I think its a dissassembled x86 version that came out of the JIT.
VB.NET & C# compilers produce .NET code whatever happens. It is only when they are run do they produce x86 at real time. That's why they sometimes load damn slow.
ok, thanks, just wanted to know.
Here's another question, I'm using c++ to do some asm(by using _asm), and the code I put is:
now after it executes that line, i get an error:Code:void asmFunc()
{
_asm jmp pFunc //pFunc is a pointer to a function
}
"Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."
Is there a way to fix this so it doesn't crash? If so, could you show me?
Hmmmm im no c++ expert but I believe it would only work properly if pFunc had no param - is this true?
You could probably find better help at the C++ forums but could you give me a bit more info?
C++ uses cdecl calling convention by default.
Cheers.
Totally pointless. C++ supports function pointers anyway so you will get a performance DECREASE using code in this way. Why are you wrapping a single line like this? Weird.Quote:
Originally Posted by benmartin101
Aye that's true because you stop c++ inlining features. But i guess he was testing the idea out - in asm ;P.
I just wanted to know for the sake of knowing. To the other question, yes, there is a parameter.
ahhh in that case your pFunc will not work because void asmFunc()
doesn't have a param
This is because c++ cdecl calling convention means that the caller of asmFunc clears up the stack. However, you jmp to pFunc which takes one param so when it returns the caller of asmFunc cannot clear 1 param off the stack because it asmFunc doesn't clear it off.
In other words it would work if you used stdcall calling convention or if you made asmFunc a 1 param function.
It won't work because jmp and call are different instructions, and the ret instruction that ends a function won't work if the function was reached by jmp. It attempts to pop the return address from the stack, but only call puts it there, so jmp/ret would return to some random place in memory, thus crashing the app. Only the stack protection guards placed in all functions when compiling in debug mode prevent this.
it should work with the jmp though if the called subroutine has no param like the calling sub. I'm not sure about the debugging because I dunno how c++ responds to a circumstance like this but you probably are right.
well, I got it to not crash if the function i'm trying to "jmp" to does not have a parameter.
"In other words it would work if you used stdcall calling convention "
used stdcall on which function? asmFunc or the function being "jmp"ed to? The function being "jmp"ed to uses stdcall.
No, it won't work, no matter the parameters. A RET instruction requires the jump to be done by a CALL exceptions, unless the programmer explicitely pushed the return address. Which would be stupid.Quote:
Originally Posted by Raedwulf
JMP <address>
->
ip = <address>
In other words, it simply jumps to the given address.
CALL <address>
->
stack.push(ip+2)
ip = <address>
It first pushes the return address to the stack (that's the current address plus the number of bytes in a call instruction - 5 or 6 on 32-bit systems, I think), the transfers control to the given location.
RET
->
ip = stack.pop()
This just pops an address off the stack and jumps there. If there's no address on the stack, it will pop off something random and thus jump to a random location. That's the __cdecl version.
RET <bytes>
->
tmp = stack.pop()
stack.pop(<bytes>)
ip = tmp
Which cleans the parameters, but is otherwise equivalent. Note that for a function without parameters, __stdcall and __cdecl are equivalent.
And even if, by some freak accident, JMP + RET happens to work for you, it's still a very bad idea. Unless you're writing a stub, which you aren't, because then you'd already know all that.
BTW, one option where it would not crash would be if the JMP was executed from within a method that has neither parameters nor local variables. In this case, the RET would return to the function that called this function, i.e.
Unless the compiler messes with the code, of course, like inserting stack protectors.Code:void fn1()
{
fn2();
}
void fn2()
{
__asm jmp fn3;
printf("This is never executed.\n");
}
void fn3()
{
} // RET generated here will return to fn1.
But otherwise, this will merely mess up your CPU's call prediction, thus slowing down your code quite a bit.
Yeah...That piece of code is what i meant. :D
Cheers.
Raedwulf