flat assembler
Message board for the users of flat assembler.

Index > Windows > pointers and arrays

Author
Thread Post new topic Reply to topic
ishkabible



Joined: 13 Sep 2010
Posts: 54
ishkabible 14 Sep 2010, 04:32
i'm pretty new to Assembly in general, i seem to already being using pointers but there is a problem, i have no clue what specifys that i am storing an address to something as apposed to the value at the address. with pointers come arrays and with both comes dynamic memory allocation. so im looking for a few things. 1) how to use pointers 2) how to use arrays 3) how to allocate space and have a pointer point to that new space 4) how to delete that old space as well. i can use malloc, realloc, ect... but i would still have to have a better grasp of pointers in assembly to do this. like i said i seem to already be using them becuase im passing variable's that in my mind should only be 1 byte and should not be mutable but yet they are. take the variable name in the following program.

Code:
format PE console
entry main
include 'INCLUDE\MACRO\import32.inc'
include 'INCLUDE\MACRO\proc32.inc'

section '.data' data readable writeable
msg db "Enter your name: ",0
chrarr db "%s",0
msg2 db "Hello %s",10,0
p db "pause>nul",0
name db ?
val  dd 0
msg3  db "and you number is: %i",10,0

section '.code' code readable executable

main:

push msg                          ;pass msg tp printf
call [printf]                     ;call printf from msvcrt.dll
                                  ;printf(msg)

push name                         ;pass name to scanf
push chrarr                       ;pass chrarr to scanf
call [scanf]                      ;call scanf from vsvcrt.dll
                                  ;scanf(chararr,name)
push name
push msg2
call [printf]

call getline
mov [val],eax
push [val]
push msg3
call [printf]

push p                            ;pass p to system
call [system]                     ;call system
                                  ;system(p)

push 0                            ;pass 0 to exit
call [exit]                       ;call exit
                                  ;exit(0)

proc getline
     mov eax,10
     ret
endp

section '.idata' import data readable
library msvcrt,'msvcrt.dll'

import msvcrt,\
printf,'printf',\
scanf,'scanf',\
system,'system',\
getchar,'getchar',\
realloc,'realloc',\
malloc,'malloc',\
free,'free',\
calloc,'calloc',\
exit,'exit'
    


what makes name mutable and what makes it(and all the other strings) able to point to address larger than 1 byte?
Post 14 Sep 2010, 04:32
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4015
Location: vpcmpistri
bitRAKE 14 Sep 2010, 06:03
The brackets say, "get what is at this address" - which really simplies the syntax. Even CALL [printf] is getting the address at label "printf" and jumping to it - not to "printf" directly. PUSH dword [chrarr] would put four bytes of the contents on the stack: "%s",0,"H" --- in the above example.

Foremost, everything is a number - which I remember causing me initial confusion those many years ago. MOV EAX,direct; MOV EAX,[indirect] --- here direct can be a literal number or an address, but indirect must be an address from which to get contents. If you want to really test your understanding then try some COM programming. Very Happy

Hope that helps a little.
Post 14 Sep 2010, 06:03
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 14 Sep 2010, 10:56
ishkabible,

"%s" scanf() conversion specification matches a sequence of non-white-space characters, yet you've provided only 1 byte as a read buffer (which can't accept even single character without overflow due to mandatory '\0' terminator). As a result, memory following name label gets overwritten during scanf() call (so val and msg3 are trashed).

For one character, use "%c" (or, even better, getchar()). To read several characters at a time, reserve more space for them (name rb 100; note rb instead of db) and use "%99s" conversion specification (one less because of '\0' terminator).

gets() can be used too, but it's more dangerous because buffer size can't be specified (you can use fgets() to circumvent this, though you must find stdin first Wink).

cdecl calling conventions (that all these functions follow) mean that your program should remove arguments from stack. With balanced stack you can use ret to finish program execution instead of exit(). There are ccall and cinvoke macros in fasm package which do this automatically.
Post 14 Sep 2010, 10:56
View user's profile Send private message Reply with quote
ishkabible



Joined: 13 Sep 2010
Posts: 54
ishkabible 14 Sep 2010, 21:08
so if im understanding this correctly brackets are differences in c/c++?

int* x;
*x = y;

is the same as

x dd ?
MOV [x], y

if this is the case then how do say 'address of' like the & operator in c/c++, how would you say x = &y? i am still pretty confused about this, i have tried several times to try and learn asm and this time i have gotten far enough that im more motivated to push forth though the confusion.
Post 14 Sep 2010, 21:08
View user's profile Send private message Reply with quote
Nameless



Joined: 30 Apr 2010
Posts: 95
Nameless 14 Sep 2010, 21:54
revolution said to me once (http://board.flatassembler.net/topic.php?t=11913 - Question 3) :
Quote:

mov eax,string1 ; a pointer to string1
mov eax,dword[string1] ; the first 4 characters of string1, NOT a pointer (since it have square brackets incase u didn't notice)


and i add
Code:
mov eax, [string1] ; move value of string1 to eax
    


Last edited by Nameless on 14 Sep 2010, 21:55; edited 1 time in total
Post 14 Sep 2010, 21:54
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 14 Sep 2010, 21:55
ishkabible,

Right. y should be simple enough (register or constant) to be encodable.

Generally, & operator from C maps to lea instruction. lea eax, [x] sets eax to the address of memory referred by [x] (x could be complex address expression like ebx+4*ecx+321). For simple address expressions (like [reg] or [constant]) it could be replaced with mov eax, x.
Post 14 Sep 2010, 21:55
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4330
Location: Now
edfed 14 Sep 2010, 22:34
Quote:

int* x;
*x = y;

is the same as

x dd ?
MOV [x], y


i always believed that int* x; meaned
Code:
xptr dd x
x  dd ?
    

and int x;
Code:
x dd ?
    


Laughing
Post 14 Sep 2010, 22:34
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 14 Sep 2010, 23:48
edfed,

int *x; means: x is declared as such variable that *x is of type int.
Post 14 Sep 2010, 23:48
View user's profile Send private message Reply with quote
ishkabible



Joined: 13 Sep 2010
Posts: 54
ishkabible 14 Sep 2010, 23:57
so lea eax,[x] would be the same as x=&y? from what i understand from the documentation lea takes the address rather than the value so wouldn't lea eax,[x] be equivalent to a pointer being set to a pointer? it would be like mov x,y witch as far as i understand would be the same as
Code:
int *x,*y; //im just declaring them for the sake of being clear;
x = y;
    


so (as far as i understand) wouldn't lea eax,x be the same as eax=&x? my understanding says that my first question in this post ("so lea eax,[x] would be the same as x=&y?") would be no, some insite on this issue would be nice.
Post 14 Sep 2010, 23:57
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 15 Sep 2010, 08:45
ishkabible,

Let's assume that
Code:
        org     1000
x       dd      1    
Using fasm conventions, «x» is simply 1000 (straight analogy from C will be «&x»), «[x]» denotes contents of memory at 1000 (simply «x», lvalue in C-speak). Register mnemonics, OTOH, always mean content of respective register. Thus mov eax, x and lea eax, [x] both are equivalent to eax = &x;.

Memory-to-memory data transfers in x86 architecture are limited to instructions with implicit operands (e.g. movs/cmps; mov [x], [y] can't be encoded). Usually this kind of data transfer is done using some intermediate storage (e.g. register).

Confusion arises mostly because variable name token in high-level languages represents two distinct entities: first, it's the name of some memory location (lvalue); second, in expression it has value (rvalue). In fasm they're syntactically different.
Post 15 Sep 2010, 08:45
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20289
Location: In your JS exploiting you and your system
revolution 15 Sep 2010, 08:50
baldr wrote:
Memory-to-memory data transfers in x86 architecture are limited to instructions with implicit operands (e.g. movs/cmps; mov [x], [y] can't be encoded).
movs (and stos/cmps etc.) also allow explicit operands.
Post 15 Sep 2010, 08:50
View user's profile Send private message Visit poster's website Reply with quote
ishkabible



Joined: 13 Sep 2010
Posts: 54
ishkabible 17 Sep 2010, 00:11
ok so i have referencing down pretty well but still cant figure out dereferencing. i have this simple program that takes z (non-pointer set to 100) uses lea to store the address of z in y and then store the contents of y in x (also a pointer) the deference x and push that value on the stack. but i have not been able to deference x, i have confirmed that x dose indeed point to z but i cant deference it.

Code:
format PE console
entry main
include 'INCLUDE\MACRO\import32.inc'
include 'INCLUDE\MACRO\proc32.inc'

section '.data' data readable writeable

x dd 0
y dd 0
z dd 100
a dd 0
msg db "%i,%i",0
cmd db "pause>nul",0

section '.code' code readable executable

main:

        lea eax,[z]       ;set eax to point to z
        mov [y],eax       ;set y to point to what eax poits to so y points to z

        mov eax,[y]         ;have eax point to y
        mov [x],eax       ;have x point to what ever eax points to
                          ;so x==y and y points to z so x points to z

        ;eax = *x  <------ here, some set of insturctions should go here to derefrence x
        push eax
        push msg          ;pass "%i,%i" to printf
        call [printf]     ;call printf
        push cmd          ;pass "pause>nul" to system
        call [system]     ;call system
        push 0            ;pass o to exit
        call [exit]       ;call exit

section '.idata' import data readable
library msvcrt,'msvcrt.dll'

import msvcrt,\
printf,'printf',\
scanf,'scanf',\
system,'system',\
getchar,'getchar',\
realloc,'realloc',\
malloc,'malloc',\
free,'free',\
calloc,'calloc',\
exit,'exit'
    
Post 17 Sep 2010, 00:11
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4330
Location: Now
edfed 17 Sep 2010, 00:33
lea eax,[eax] <=> *x=*x.

mov eax,[eax] <=> x=*x?

mov eax,eax <=> x=x?
Post 17 Sep 2010, 00:33
View user's profile Send private message Visit poster's website Reply with quote
ishkabible



Joined: 13 Sep 2010
Posts: 54
ishkabible 17 Sep 2010, 00:39
o wait i found a solution, you mov x to eax (or other 32-bit register) the to call on the dereferenced use dword[eax]. i say it looking at some code where they used [eax] and i thought "doesn't it always work like that" but i then realized that this took it one step further and gave you what was at the address stored at eax. is this the best way to do this?
Code:
format PE console
entry main
include 'INCLUDE\MACRO\import32.inc'
include 'INCLUDE\MACRO\proc32.inc'

section '.data' data readable writeable

x dd 0
y dd 0
z dd 100
a dd 0
msg db "%i,%i",0
cmd db "pause>nul",0

section '.code' code readable executable

main:

        lea eax,[z]       ;set eax to point to z
        mov [y],eax       ;set y to point to what eax poits to so y points to z

        mov eax,[y]         ;have eax point to y
        mov [x],eax       ;have x point to what ever eax points to
                          ;so x==y and y points to z so x points to z

        ;eax = *x  <------ here, some set of insturctions should go here to derefrence x
        mov eax,[x]
        push dword[eax]
        push [x]
        push msg          ;pass "%i,%i" to printf
        call [printf]     ;call printf
        push cmd          ;pass "pause>nul" to system
        call [system]     ;call system
        push 0            ;pass o to exit
        call [exit]       ;call exit

section '.idata' import data readable
library msvcrt,'msvcrt.dll'

import msvcrt,\
printf,'printf',\
scanf,'scanf',\
system,'system',\
getchar,'getchar',\
realloc,'realloc',\
malloc,'malloc',\
free,'free',\
calloc,'calloc',\
exit,'exit'
    
Post 17 Sep 2010, 00:39
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4330
Location: Now
edfed 17 Sep 2010, 01:13
Code:
        mov eax,z
        mov [y],eax      ;set y to point to what eax poits to so y points to z
        mov [x],eax       ;have x point to what ever eax points to
                          ;so x==y and y points to z so x points to z
    
Post 17 Sep 2010, 01:13
View user's profile Send private message Visit poster's website Reply with quote
ishkabible



Joined: 13 Sep 2010
Posts: 54
ishkabible 17 Sep 2010, 01:37
i don't understand what your trying to tell me about my code. i understand it is redundant to do it that way, i'm just trying to replicate a simple program i made in c. i am shooting for literal unoptimized assembly, i figure if i can have a good strong way to translate c to assembly then i can handle optimizations after that Smile

Code:
#include <stdio.h>

int main() {
   int *x,*y,z=100;
   y=&z;
   x=y;
   printf("%i",*x);
} 
    


O and about the mov eax,z instead of lea eax,[z] i would learn the habit of using this (again, unless optimizations dictate otherwise) as this allows me to use complex offsets if im not mistaken. so if i had an array of values then i would want to lea instead of mov becuase i could access it like this [z+index*size+offset] right?
Post 17 Sep 2010, 01:37
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.