Look at this screenshot of a Visual C++ debugger session:
(source: lviv.ua)
The execution point is now inside a virtual function. "mDb" is a reference to an object which is the member of that class. "mDb" has the type CDbBackend&. There is only one thread. The values in the red rectangles should be equal, ... but they're not. How can this be possible?
The code being debugged has been instrumented with BoundsChecker (a memory debugger and profiler). The discrepancy leads to a crash later on. Non-instrumented code doesn't lead to any of these effects. I think it's too early to blame BoundsChecker - it could well be a hidden bug in my program which BoundsChecker has revealed, which is why I'm very inclined to understand the situation.
The assembly generated for the "b = &mDb" statement is as follows, in case it's relevant. Stepping thhrough this assembly, with watch and registers visible, is captured here (500kb avi file).
007AB7B0 push 4
007AB7B2 push 80000643h
007AB7B7 push 4
007AB7B9 push 0C0002643h
007AB7BE lea eax,[ebp-10h]
007AB7C1 push eax
007AB7C2 call dword ptr [_numega_finalcheck_C_110456 (8FA8A8h)]
007AB7C8 mov eax,dword ptr [eax]
007AB7CA add eax,1CCh
007AB7CF push eax
007AB7D0 call dword ptr [_numega_finalcheck_C_110456 (8FA8A8h)]
007AB7D6 mov dword ptr [ebp-70h],eax
007AB7D9 push dword ptr [ebp-70h]
007AB7DC push 4
007AB7DE push 50000643h
007AB7E3 lea eax,[ebp-20h]
007AB7E6 push eax
007AB7E7 call dword ptr [_numega_finalcheck_Y_110456 (8FA8ECh)]
007AB7ED mov ecx,dword ptr [ebp-70h]
007AB7F0 mov ecx,dword ptr [ecx]
007AB7F2 mov dword ptr [eax],ecx
Please rebuild and test it again. (I know it sounds stupid :)
The code is compiled in debug mode w/o any optmizations, right? I guess so. But, in the disassembly, no symbolic information is presented. I can only see [ebp - offset]; this should be represented as some symbolic name such as b. Be sure turn on "Show symbol names" in disassembly view.
I'm not sure the disassembly code you pasted are the code for b = &mDb. It looks like [ebp-10h] or [ebp-70h] would be b, but mDb does not seem to be here. All the code in here just is calling instrumented function. Could you give more disassembly with source code around them?
I have an experience where debugging information is incorrectly generated, so symbolic debugging gave an incorrect value. My workaround was that changing member variable layout and putting some padding in local stack. But, I'm not sure that this was a really compiler's bug. I was working on Visual Studio 2008 with Intel C/C++ compiler, and the project was pretty complex.
The information is somewhat insufficient to resolve this problem. It would be better if you give more disassembly.
Is mDb also of type CDbBackend? If not, then discrepancy is due to casting.
Given:
class A
{
// Stuff
};
class B : public A
{
// More stuff
};
B *b = new B;
A *a = (A *)&b;
then b and a might or might not be equivalent depending on what exactly "Stuff" and "More Stuff" are. The biggest things that will change the pointer castings are virtuals and multiple inheritance. If this is the case in your example then your debugger's output is correct and normal behavior. If you expand the class view for mDb, I wouldn't be surprised if you find a CDbBackend pointer contained within it that matches your second output below.
Related
I wrote this code in emu8086 and it goes well in the emulator but when I'm trying to compile it with NASM it's throwing me up the error: "operation size not specified", help someone?
add bx,[3565]
sub bx,0xcc
mov [bx],0CCh
NASM can't figure out what you meant by a line like mov [bx],0CCh. Clearly,
this sets something to 0CCh. But do you want to have bx pointing to a single byte
, short, long, ...? This will manifest itself as the fairly self-explanatory
error: operation size not specified in NASM. You could avoid the error specifying the type, as shown below:
SECTION .text
global start
start:
add bx,[3565]
sub bx,0xcc
mov byte [bx],0CCh
That'd assemble it ok... of course, don't try to run it as it is, it'll produce EXCEPTION_ACCESS_VIOLATION. Just open it with a debugger and you'll understand why.
Super noob here. I'm doing a "hello world" type program in LC-3 assembly language and I simply don't know how to print more than one string to the console. I need 4 strings on separate lines that are my class, name, project and goodbye. Right now all I can seem to print in the class.
.ORIG x3000
LOOP LEA R0, CLASS
LD R1, NAME
LD R2, PROJECT
LD R3, GOODBYE
PUTS
HALT
CLASS .STRINGZ "CS101\n"
NAME .STRINGZ "JOHN\n"
...
.END
How would I get the other 3 to print? Thanks!
The Z in .STRINGZ means zero terminated. That is you have declared separate strings. If you want to print them all, you need to invoke PUTS multiple times. Alternatively, make it a single string with embedded newlines. Then you can print the whole thing in one go.
I know something is happening with the command line arguments but I don't know what. Can someone walk me through this code?
0x401050 <main>: push %ebp
0x401051 <main+1>: mov %esp,%ebp
0x401053 <main+3>: sub $0x8,%esp
0x401056 <main+6>: and $0xfffffff0,%esp
0x401059 <main+9>: mov $0x0,%eax
0x40105e <main+14>: mov %eax,0xfffffffc(%ebp)
0x401061 <main+17>: mov 0xfffffffc(%ebp),%eax
0x401064 <main+20>: call 0x4013a0 <_alloca>
0x401069 <main+25>: call 0x401430 <__main>
0x40106e <main+30>: mov $0x0,%edx
0x401073 <main+35>: add 0x8(%ebp),%edx
0x401076 <main+38>: mov %edx,%eax
0x401078 <main+40>: leave
0x401079 <main+41>: ret
Without letting us know how your function is called and how the called ones are declared, we are not able to actually help you.
For Example, it's not clear whether alloca and _main are cdecl, stdcall, fastcall, etc. and how many parameters they expect, you would need to investigate them as well and see how they set up, access and clean up the stack.
As for your code, it looks kind of weird..
It calls alloca and _main without cleaning up the stack, so either they aren't cdecl or the "sub esp,8" allocates space for both calls. It then zeros eax and moves it into ebp-4, which could be a parameter to those calls. However, most of the stack is uninitialized. After calling alloca it doesn't do anything with eax, so either _main is some kind of fastcall and expects a parameter in eax or your code is plain weird. Like ughoavgfhw already said, in the end the function returns its own first parameter.
Also, you should attach a debugger and single step through your code to fully comprehend it.
I have an inline assembly code like this
__asm
{
MOV dword ptr [esp+4], 12345678h
}
I want to get the value of at [esp+4] in a separate variable before 12345678h is written there, which I can use further in my c++ code.
According to this manual which I found in less than five minutes, variable identifiers are valid within __asm blocks. I then found a relevant example by clicking the "Accessing C or C++ data in __asm blocks" link under the "What do you want to know more about?" section of that manual:
A great convenience of inline assembly is the ability to refer to C or
C++ variables by name. An __asm block can refer to any symbols,
including variable names, that are in scope where the block appears.
For instance, if the C variable var is in scope, the instruction
__asm mov eax, var
stores the value of var in EAX.
What does .string do in assembly?
In an inline asm call in c, I wrote
.string \"Hello World\"
1) Can somebody give me an overview of how .string works?
2) Somehow that value gets saved in %esi. Why?
3) How can I append a return carriage on the end? \n doesn't work
.string is an assembler directive in GAS similar to .long, .int, or .byte. All it does is create and initialize memory for you to use in your program. The .string directive will automatically null-terminate the string with [\0] for you. In this case, the assembler is allocating space for 14 characters in 14 contiguous bytes of memory. If you were to look at the memory, you would see this:
["][H][e][l][l][o][ ][W][o][r][l][d]["][\0]
Except in hexadecimal rather than characters. I'm not sure how or why %esi points to the string (it's either an assembler setting I'm not familiar with or has been set that way on a line of code you're not showing us). What it means is that %esi "points" to the first byte of the string - in this case the first ["]. You can use the %esi register to loop through the bytes using an offset (%esi + 5 would be [o]) or by incrementing the register itself.
To add a newline you might want to try \x0D\x0A instead of \n.
It just emits a sequence of characters into the appropriate code/data section. See this and this (they use .ascii, though).
Show us the code.
Try \\n or \12 or \xa.