Discussion:
newbie learning: question about an instruction
(too old to reply)
G G
2019-06-13 21:46:11 UTC
Permalink
; program from book
; Windows 64-bit Assembly Language Programming
; Quick Start: Intel X86-64, SSE, AVX




includelib kernel32.lib ; Windows kernel interface
GetStdHandle proto ; Function to retrieve I/O handle
WriteConsoleA proto ; Function that writes to command window
Console equ -11 ; Device code for console text output.
ExitProcess proto

.code
mainCRTStartup proc

sub RSP,40 ; Reserve "shadow space" on stack.

; Obtain "handle" for console display monitor I/O streams

mov RCX,Console ; Console standard output handle
call GetStdHandle ; Returns handle in register RAX
mov stdout,RAX ; Save handle for text display.

; Display the "Hello World" message.

mov RCX,stdout ; Handle to standard output device
lea RDX,hwm ; Pointer to message (byte array).
mov R8,lengthof hwm ; Number of characters to display
lea R9,nbwr ; Number of bytes actually written.
call WriteConsoleA ; Write text string to window.

add RSP,40 ; Replace "shadow space" on stack
mov RCX,0 ; Set exit status code to zero.
call ExitProcess ; Return control to Windows.

mainCRTStartup endp

.data
hwm byte "Hello World"
stdout qword ? ; Handle to standard output device
nbwr qword ? ; Number of bytes actually written

end



my questions are about shadow space and lea R9,nbwr

RSP - register star pointer is pointing to a location here 40 is subtracted
from that address? is 40, 64bit memory address where 40 bytes are
being acquired ?

where does nbwr get it's value to be move into register R9?
s***@nospicedham.yahoo.com
2019-06-14 13:45:22 UTC
Permalink
Post by G G
; program from book
; Windows 64-bit Assembly Language Programming
; Quick Start: Intel X86-64, SSE, AVX
includelib kernel32.lib ; Windows kernel interface
GetStdHandle proto ; Function to retrieve I/O handle
WriteConsoleA proto ; Function that writes to command window
Console equ -11 ; Device code for console text output.
ExitProcess proto
.code
mainCRTStartup proc
sub RSP,40 ; Reserve "shadow space" on stack.
; Obtain "handle" for console display monitor I/O streams
mov RCX,Console ; Console standard output handle
call GetStdHandle ; Returns handle in register RAX
mov stdout,RAX ; Save handle for text display.
; Display the "Hello World" message.
mov RCX,stdout ; Handle to standard output device
lea RDX,hwm ; Pointer to message (byte array).
mov R8,lengthof hwm ; Number of characters to display
lea R9,nbwr ; Number of bytes actually written.
call WriteConsoleA ; Write text string to window.
add RSP,40 ; Replace "shadow space" on stack
mov RCX,0 ; Set exit status code to zero.
call ExitProcess ; Return control to Windows.
mainCRTStartup endp
.data
hwm byte "Hello World"
stdout qword ? ; Handle to standard output device
nbwr qword ? ; Number of bytes actually written
end
my questions are about shadow space and lea R9,nbwr
I'll take a stab at it..
Post by G G
RSP - register star pointer is pointing to a location here 40 is subtracted
from that address?
SP is 'Stack Pointer', 'R' is register size, qword. So, RSP is the stack pointer register in 64 bits. 40 (bytes I assume) is 8 bytes (qword) * 5 qwords. This is a way to allocate _space_ for 5 automatic variables on the stack.
Post by G G
is 40, 64bit memory address where 40 bytes are
being acquired ?
No, space for 5 automatic variables is allocated in the stack frame, perhaps the called function needs these, the program fragment you show doesn't touch them.
Post by G G
where does nbwr get it's value to be move into register R9?
It looks like WriteConsoleA needs some values passed in registers to do its work.
lea R9,nbwr ; Number of bytes actually written.
So R9 receives the effective address of nbwr (its pointer), it looks like the function call will return a value in the variable whose address is passed in R9.

So that is where nbwr gets its value, it is a returned result of WriteConsoleA.

hth,

Steve
G G
2019-06-14 14:23:55 UTC
Permalink
Post by s***@nospicedham.yahoo.com
Post by G G
; program from book
; Windows 64-bit Assembly Language Programming
; Quick Start: Intel X86-64, SSE, AVX
includelib kernel32.lib ; Windows kernel interface
GetStdHandle proto ; Function to retrieve I/O handle
WriteConsoleA proto ; Function that writes to command window
Console equ -11 ; Device code for console text output.
ExitProcess proto
.code
mainCRTStartup proc
sub RSP,40 ; Reserve "shadow space" on stack.
; Obtain "handle" for console display monitor I/O streams
mov RCX,Console ; Console standard output handle
call GetStdHandle ; Returns handle in register RAX
mov stdout,RAX ; Save handle for text display.
; Display the "Hello World" message.
mov RCX,stdout ; Handle to standard output device
lea RDX,hwm ; Pointer to message (byte array).
mov R8,lengthof hwm ; Number of characters to display
lea R9,nbwr ; Number of bytes actually written.
call WriteConsoleA ; Write text string to window.
add RSP,40 ; Replace "shadow space" on stack
mov RCX,0 ; Set exit status code to zero.
call ExitProcess ; Return control to Windows.
mainCRTStartup endp
.data
hwm byte "Hello World"
stdout qword ? ; Handle to standard output device
nbwr qword ? ; Number of bytes actually written
end
my questions are about shadow space and lea R9,nbwr
I'll take a stab at it..
Post by G G
RSP - register star pointer is pointing to a location here 40 is subtracted
from that address?
SP is 'Stack Pointer', 'R' is register size, qword. So, RSP is the stack pointer register in 64 bits. 40 (bytes I assume) is 8 bytes (qword) * 5 qwords. This is a way to allocate _space_ for 5 automatic variables on the stack.
Post by G G
is 40, 64bit memory address where 40 bytes are
being acquired ?
No, space for 5 automatic variables is allocated in the stack frame, perhaps the called function needs these, the program fragment you show doesn't touch them.
Post by G G
where does nbwr get it's value to be move into register R9?
It looks like WriteConsoleA needs some values passed in registers to do its work.
lea R9,nbwr ; Number of bytes actually written.
So R9 receives the effective address of nbwr (its pointer), it looks like the function call will return a value in the variable whose address is passed in R9.
So that is where nbwr gets its value, it is a returned result of WriteConsoleA.
hth,
Steve
but i'm missing somthething here. lea R9, nbwr comes before the
WriteConsoleA procedure even though it may return a value
wouldn't nbwr contain garbage when it is move into R9?
Mel
2019-06-14 15:15:56 UTC
Permalink
On Fri, 14 Jun 2019 07:23:55 -0700 (PDT), G G
On Friday, June 14, 2019 at 9:46:01 AM UTC-4,
Post by s***@nospicedham.yahoo.com
Post by G G
; program from book
; Windows 64-bit Assembly Language Programming
; Quick Start: Intel X86-64, SSE, AVX
includelib kernel32.lib ; Windows kernel interface
GetStdHandle proto ; Function to retrieve I/O handle
WriteConsoleA proto ; Function that writes to command window
Console equ -11 ; Device code for console text output.
ExitProcess proto
.code
mainCRTStartup proc
sub RSP,40 ; Reserve "shadow space" on stack.
; Obtain "handle" for console display monitor I/O streams
mov RCX,Console ; Console standard output handle
call GetStdHandle ; Returns handle in register RAX
mov stdout,RAX ; Save handle for text display.
; Display the "Hello World" message.
mov RCX,stdout ; Handle to standard output device
lea RDX,hwm ; Pointer to message (byte array).
mov R8,lengthof hwm ; Number of characters to display
lea R9,nbwr ; Number of bytes actually written.
call WriteConsoleA ; Write text string to window.
add RSP,40 ; Replace "shadow space" on stack
mov RCX,0 ; Set exit status code to zero.
call ExitProcess ; Return control to Windows.
mainCRTStartup endp
.data
hwm byte "Hello World"
stdout qword ? ; Handle to standard output device
nbwr qword ? ; Number of bytes actually written
end
my questions are about shadow space and lea R9,nbwr
I'll take a stab at it..
Post by G G
RSP - register star pointer is pointing to a location here 40 is subtracted
from that address?
SP is 'Stack Pointer', 'R' is register size, qword. So, RSP is
the stack pointer register in 64 bits. 40 (bytes I assume) is 8
bytes (qword) * 5 qwords. This is a way to allocate _space_ for 5
automatic variables on the stack.
Post by s***@nospicedham.yahoo.com
Post by G G
is 40, 64bit memory address where 40 bytes are
being acquired ?
No, space for 5 automatic variables is allocated in the stack
frame, perhaps the called function needs these, the program fragment
you show doesn't touch them.
Post by s***@nospicedham.yahoo.com
Post by G G
where does nbwr get it's value to be move into register R9?
It looks like WriteConsoleA needs some values passed in registers to do its work.
lea R9,nbwr ; Number of bytes actually written.
So R9 receives the effective address of nbwr (its pointer), it
looks like the function call will return a value in the variable
whose address is passed in R9.
Post by s***@nospicedham.yahoo.com
So that is where nbwr gets its value, it is a returned result of WriteConsoleA.
hth,
Steve
but i'm missing somthething here. lea R9, nbwr comes before the
WriteConsoleA procedure even though it may return a value
wouldn't nbwr contain garbage when it is move into R9?
Lea loads address
--
Press any key to continue or any other to quit
R.Wieser
2019-06-14 15:37:02 UTC
Permalink
G G,
lea R9, nbwr comes before the WriteConsoleA
procedure even though it may return a value wouldn't
nbwr contain garbage when it is move into R9?
Your code is using LEA, not MOV. LEA gets 'the addres of' (the memory the
variable is located at). In short: It is how you get a variable 'by
reference' (instead of 'by value').

Said another way: WriteConsoleA is given /a pointer to/ a variable, so it
knows where (which bytes in memory) to write its result (the number of bytes
read) into. If it would have been 'by value' it would have not been able
to return that count.

So yes, it /points to/ a variable with unknown contents. But that does not
matter, as the function will overwrite it.

Hope that helps.

Regards,
Rudy Wieser
G G
2019-06-14 16:07:51 UTC
Permalink
Post by R.Wieser
G G,
lea R9, nbwr comes before the WriteConsoleA
procedure even though it may return a value wouldn't
nbwr contain garbage when it is move into R9?
Your code is using LEA, not MOV. LEA gets 'the addres of' (the memory the
variable is located at). In short: It is how you get a variable 'by
reference' (instead of 'by value').
Said another way: WriteConsoleA is given /a pointer to/ a variable, so it
knows where (which bytes in memory) to write its result (the number of bytes
read) into. If it would have been 'by value' it would have not been able
to return that count.
So yes, it /points to/ a variable with unknown contents. But that does not
matter, as the function will overwrite it.
Hope that helps.
Regards,
Rudy Wieser
got it! i think.

thanks.
Rick C. Hodgin
2019-06-14 14:54:03 UTC
Permalink
Post by G G
but i'm missing somthething here. lea R9, nbwr comes before the
WriteConsoleA procedure even though it may return a value
wouldn't nbwr contain garbage when it is move into R9?
Do you have an C/C++ experience? It's doing basically this:

void my_function(int* p)
{
*p = 9;
}

int main()
{
// nbwr is defined, but never initialized
int nbwr;

// Call a function with its address
my_function(&nbwr); // param is equivalent of "lea r9,nbwr"

// Display the value of nbwr
// It was never populated locally, but only in the called
// function.
printf("Value = %d\n", nbwr);

return 0;
}

When you load the address of nbwr into r9, it's storing the lo-
cation in memory where nbwr's value exists. This allows the
called function to write a value there, updating nbwr remotely
by its pointed-to location. It's a very common way to obtain
output parameters as the called functions can update local data
if they know where it is (hence the use of lea = load effective
address of the target variable).

-----
Also, the reason why you see extra bytes being added for stack
space is a Windows need. It adds an area called "shadow space"
so that you can use that area to load existing register values
into that location without having to issue lots of PUSH/POP in-
structions.

Personally I think it's an incredible and ridiculous waste. It
tries to cast the role of called functions into a mold that is
a one-size fits all. It's wasteful and an inappropriate use of
machine resources in my opinion.
--
Rick C. Hodgin
Loading...