flat assembler
Message board for the users of flat assembler.
Index
> Windows > pointers and arrays |
Author |
|
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. Hope that helps a little. |
|||
14 Sep 2010, 06:03 |
|
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 ). 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. |
|||
14 Sep 2010, 10:56 |
|
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. |
|||
14 Sep 2010, 21:08 |
|
Nameless 14 Sep 2010, 21:54
revolution said to me once (http://board.flatassembler.net/topic.php?t=11913 - Question 3) :
Quote:
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 |
|||
14 Sep 2010, 21:54 |
|
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. |
|||
14 Sep 2010, 21:55 |
|
edfed 14 Sep 2010, 22:34
Quote:
i always believed that int* x; meaned Code: xptr dd x x dd ? and int x; Code: x dd ? |
|||
14 Sep 2010, 22:34 |
|
baldr 14 Sep 2010, 23:48
edfed,
int *x; means: x is declared as such variable that *x is of type int. |
|||
14 Sep 2010, 23:48 |
|
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. |
|||
14 Sep 2010, 23:57 |
|
baldr 15 Sep 2010, 08:45
ishkabible,
Let's assume that Code: org 1000 x dd 1 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. |
|||
15 Sep 2010, 08:45 |
|
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). |
|||
15 Sep 2010, 08:50 |
|
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' |
|||
17 Sep 2010, 00:11 |
|
edfed 17 Sep 2010, 00:33
lea eax,[eax] <=> *x=*x.
mov eax,[eax] <=> x=*x? mov eax,eax <=> x=x? |
|||
17 Sep 2010, 00:33 |
|
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' |
|||
17 Sep 2010, 00:39 |
|
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 |
|||
17 Sep 2010, 01:13 |
|
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
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? |
|||
17 Sep 2010, 01:37 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.