Hello...
1. If I pass a pointer from C++ to ASM, is it considered an INTEGER VALUE and it is passed into the registers RCX/RDX/R8/R9 (or the stack if necessary) as a normal number? And if so, is it only the OFFSET and the current DATA SEGMENT is assumed to contain the data?
Pointers are normal integer values and these integer values are used as memory addresses. Their sizes depends on the architecture.
In x86-64 mode all addresses are 64 bits in size (but only 48 bits are used - 52 if PSE is enabled for a page). The remaining bits must be a copy of the last valid bit (this is called "cannonical addressing" - take a look at topic 3.3.7 on Intel's "Software Development Manual, vol 1"). For exemple, this address is cannonical: 0x7fffffffffff; but this is not: 0x800000000000, because only bits 0~47 are valid and in the later case bit 48=1. The cannonical address here is 0xffff800000000000).
It is useful to know abour cannonical addressing, but with 48 bits it's possible to address 256 TiB of memory!!! And with 52 bits, 2 PiB!!! Without worrying about cannonization!
Also, in x86-64 mode no selector registers are used, except CS (only to hold the Current Privilege Level), FS and GS. The memory is always flat regarding segmentation. The protection is enforced by the paging mechanism. Take a look at any simple program with GDB and you'll see something like this:
(gdb) l
1 bits 64
2 default rel
3
4 global _start
5 _start:
6 xor edi,edi
7 mov eax,60
8 syscall
(gdb) b 6
Breakpoint 1 at 0x400080: file test.asm, line 6.
(gdb) r
Starting program: /mnt/vol2/Work/tmp/test
Breakpoint 1, 0x0000000000400080 in _start ()
(gdb) info registers
rax 0x0 0
rbx 0x0 0
rcx 0x0 0
rdx 0x0 0
rsi 0x0 0
rdi 0x0 0
rbp 0x0 0x0
rsp 0x7fffffffdcf0 0x7fffffffdcf0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0x400080 0x400080 <_start>
eflags 0x202 [ IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
See that DS-ES are all zero? CS and SS holds information used by the kernel, but the processor will ignore everything, except the RPL field of CS.
2. If I need to pass different size arguments (byte, word, dword, qword), are they passed as full 64-bits values and just have to extract the required size, for example CL, CX, ECX or RCX according to the parameter size in C++? And, I suposse that no matter if it is a signed or unsigned value, the assembly function processes the value in the required way depending on the expected data size, let be an unsigned integer or a signed integer (maybe in two's complement if highest bit is set)?
Yes, but you don't need to initialize all 64 bits. For instance:
int f(int x) { return x+x; }
...
y=f(10);
Creates code like this:
f:
; The compiler uses RDI here to avoid insering an extra prefix
; to the instruction (0x67). Otherwise, the instruction could be
; lea eax,[edi+edi].
lea eax,[rdi+rdi]
ret
...
mov edi,10 ; EDI, not RDI!
call f
...
For
byte sized arguments there are aliases to RDI and RSI: DIL and SIL.
If an integer is interpreted as signed or unsigned is a matter of using the flags. All integer arithmetic is done if the data is unsigned and sets CF and OF accordingly.
[]s
Fred