Click here to Skip to main content
15,611,312 members

Comments by den2k88 (Top 42 by date)

den2k88 9-Jan-23 3:36am View    
Bad planning on your part does not imply emergency on our part.
den2k88 1-Jun-22 9:36am View    
Sadly no university ever teaches how to use a debugger. A part of this comes from the common usage of plain gcc, with gdb being a steaming pile of youknowwhat to use, and a part from the teacher being teachers and never having worked in real development.

Basically, I had to teach myself the use of a debugger well after graduation, when I started my first job - I used to debug image analysis algorithms with printfs... that's the sorry state of CS education nowadays.
den2k88 29-Oct-21 16:42pm View    
1) yes, unless using some shortcut instructions all this bookkeeping has to be done manually: welcome to Assembly.
When a function begins the first thing it should do is to push the current values of ALL the registers it intends to modify. At the end of the function it has to restore them. This is important because the calling function might have been using them.
Also it depends on the calling convention, in some rare cases it the calling function that has to keep a copy of the registers it needs untouched but it's very very rare.

Also it is possible to repurpose some registers, to a degree. Might have some instructions not working properly though, consider that x86 is a CISC architecture, which means it has a LOT of instructions.

2) If you can find notes about a Computer Architecture courde based on x86 it would be the best: understanding the architecture is the first step in assembly. The Intel manuals for IA32 assembly are free and well done, keep in mind that they are product manuals therefore quite dry and fast on the basics and then there is a LONG reference manual for the gazillion instructions. They are still worth a reading, when I used them I already knew the architecture and glossed over that part, it might be very good.

As for MASM, its manual is the only source. It is one of the assemblers and it has its own macros and syntax.

Sorry for the curtness but I'm on vacation and writing from my smartphone, which is not particularly easy :D
den2k88 28-Oct-21 3:39am View    
> About STRUCT being a macro, does this mean that the MASM32 Assembler converts that code into something that looks like the ebp snippet?

Yes, there should be the compilation option to show the expanded code before the 1:1 translation in machine code.

> And whenever you make an object in C(++) that is a struct/class, does the compiler simply treat every member of every struct as global variables?

Yes and no, usually global variables are placed in a separate segment of memory while local variables are always present only on the current stack. Also everything created with malloc() or new lives in a different area of memory, called heap, which is managed by the OS through low level APIs.

> Also, how does malloc() fit into this way of keeping track of things?

It uses an external memory segment which is "unlimited", the size and location of which is actually managed by the OS. There are OSes out there without heap, therefore without malloc and new - mostly for microcontrollers.

Does ebp always point at the end of the stack? Yes, in x86 and derived architectures EBP is a special purpose register which is also used by some CPU instructions. You may repurpose it but you have to restore its original content before returning from the function if you want the program to work - attacking EBP is (was) a good way to execute exploits, the dreaded stack overflow attack.

> Why 4 bytes before its start? Does that mean 4 bytes before the end of the stack? I thought eax was the primary/preferred register to put return values into.

It depends on the calling convention of the function, which defines where the function is expecting its arguments, where it stores its return value and who is responsible for cleaning up the function stack. The convention I know of are cdecl, stdcall and fastcall. The one you refer with eax as return register should be fastcall if I remember correctly.

Also I may have not been completely accurate on what the snippet does: watching more thoroughly it should be placing the argument of the printf 4 bytes before the current stack pointer, but IIRC the stack pointer grows "upwards", from high address to low address.

Consider that I'm not actively developing in x86 assembler since half a decade, so while I'm fairly sure the gist of my answer is correct I probably misplaced some explanation, especially since you're making more and more in-depth questions ;P
den2k88 27-Oct-21 3:17am View    
They don't, assembler is a direct translation of machine code, it works at the machine level. At that level, memory is flat, there are only addresses. Every kind of logic or structure is added by the programmer, in Assembly, or by the language when using high level languages.

A variable is simply the content of a memory location, so is a member of a structure, the address of a method, everything. What do they mean in context is decided by the language constructs and the programmer's logic.

Down to the assembly there are no objects, no methods, no variables. Only a flat area of memory. Methods are functions, functions are lists of assembly instructions.

As for that snippet, it *should* (I am a bit rusty in MASM) access the stack (EBP register points at the end of the stack) 4 bytes before its start, which should be the location of the return value in function calls. It is not properly an array but raw pointer arithmetics in raw memory.