flat assembler
Message board for the users of flat assembler.

Index > Main > Fasm Experience

Author
Thread Post new topic Reply to topic
DarrenBall



Joined: 27 Nov 2009
Posts: 3
DarrenBall 27 Nov 2009, 16:41
Help me please..

I'm learning Fasm but can't find the tutorials i need on internet ?

OK ppl -

Say i wrote a PE called msgbox, and all this app did was disply a msgbox with the message = msg -- as below

msg1 db "This msg Box" & 13
msg2 db "Darren Ball"
msg = msg1 & msg2

Now when i run the full app how can i load in the pointer to the data section of my code & change at run time msg2 ?

If it makes it easier to understand what i want to do -

From the command line

c:\ msgbox "intel processor"

now when it runs it displays the msg "This msg Box "
"intel processor"
I know that when i have the pointer to the data segment of my app i would have to calculate the position of msg2 - But how ?
Post 27 Nov 2009, 16:41
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 27 Nov 2009, 18:41
msg db "message" declares a FASM variable called 'msg' which is the address where it is located (it is not stored in the exe), and puts the message "message" there.

You access it by writing 'msg'.

Code:
mov eax, msg2    
puts in eax the address where msg2 is written. (it's static global variable of course)

you can, of course, use 'msg2+5' if you want 5 characters forward, etc...

if this isn't what you asked for, sorry I don't get what you're saying.
Post 27 Nov 2009, 18:41
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1900
DOS386 28 Nov 2009, 08:20
> I'm learning Fasm but can't find the tutorials i need on internet ?

Here Smile ... there are harly other places.

> If it makes it easier to understand what i want to do

NO. Post offending code and tell what happens vs what you excepted. Also, tell for what OS you develop and pick appropriate subforum.
Post 28 Nov 2009, 08:20
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 28 Nov 2009, 10:30
DOS386 wrote:
Post offending code and tell what happens vs what you excepted. Also, tell for what OS you develop and pick appropriate subforum.

Here's code for GLaDOS.
It is expected to give me cake, but instead it is offending me. Please help!


Code:
if cake ~ eq lie
display "Here have some cake"
mov byte[mouth],cake
else
display "HAHA NOOB YOU FELL FOR IT! SUCKER!!!"
end if    

_________________
Post 28 Nov 2009, 10:30
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
DarrenBall



Joined: 27 Nov 2009
Posts: 3
DarrenBall 28 Nov 2009, 11:28
Thanks Borsuc, Dos386 and Azu,

But wot i was trying to ocumplish was to understand how windows assigns memory space per app ( My Program ).

i understand that msg2, msg1 & msg are pointers to the variable address spaces - but when window loads my app, it will give it such things as -

memory space ( data, code, stack ..)
It's memory space if it was an old 16bit asm app i could calculate using sgment and offset to gain access to the memory locations (8bit chunks)
but Windows gives it a location and we can access using the offset into that location ?
This is the problem i'm trying to resolve - How to get the segment start of my APP.
Then i'm guessing at the beginning of my APP's address space i could fetch info like :-

Handle - given to my app by windows
name - name of my .exe
Size - of my app in the memory space - i'm assuming windows calculates this so the Processor doesn't run into any other app in neighbouring address spaces ?

Data - Start of my data segment - where my variables and any constants are

Code - Start of my Code segment - This could be handy for self modifying code at run time.

Stack - Start of my Stack segment - I know that each app at run time initialises it's own stack - which windows destroys as part of the app's closing routine's.

Thank you all for your comments and i hope you can see that i'm trying to understand how the app is running when i implement it ?
Post 28 Nov 2009, 11:28
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 29 Nov 2009, 02:44
Windows loads sections from the PE executable into specific addresses. They are assigned automatically (although nothing stops you from modifying them, but you'll have to use manual PE I think).

Anyway, the code usually is loaded at 0x00400000 base address -- i.e 0x00400001 will be byte 2 of the code.

As you can see, the addresses are pretty much static per application. Every application has its own address space, so it is perfectly ok for two apps to both have different code at 0x00400000 -- this is called virtual memory and let's just keep it at that so you don't get confused ok?

When FASM creates a fasm "variable", this variable exists only within fasm, not in the compiled executable -- it's just information for compiling. For example, if you want to find the address of the second instruction in the following code:
Code:
xor eax, eax
xor ecx, ecx    
and you want to use the address of the second instruction, you can use a label (labels can be used as variables):
Code:
xor eax, eax
second_instruction:  ; this is a label
xor ecx, ecx    
Then let's say you want to put in edx that address, but +1 offset (just an example) you can do this:
Code:
mov edx, second_instruction+1  ; fasm will replace second_instruction with the address and add 1, then make the instruction    


In this example it would be "mov edx, 0x00400002+1" or "mov edx, 0x00400003" stored in the exe after compilation (xor eax, eax takes 2 bytes), but really you don't want to hardcode them so you use variables/labels Very Happy

yeah you can pretty much interchange variables and labels as you wish. Smile

Hope that clarifies some stuff about FASM and memory outline.

Data is the same as code, after all, code is "data" itself. Wink

Also, that's what "x db 5" does too, it makes a label at that address, it's the same as:
Code:
x: db 5    
or
Code:
x:
db 5    
(same thing, there's nothing in between anyway)

_________________
Previously known as The_Grey_Beast
Post 29 Nov 2009, 02:44
View user's profile Send private message Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 789
Location: Adelaide
sinsi 29 Nov 2009, 03:16
Borsuc, the MZ header is loaded at 00400000, the first code is usually at 00401000 (4K aligned sections in memory).
Post 29 Nov 2009, 03:16
View user's profile Send private message Reply with quote
DarrenBall



Joined: 27 Nov 2009
Posts: 3
DarrenBall 29 Nov 2009, 13:46
Thanks Borsuc, sinsi.

I'm slowly understanding - i get it now that labels are assembler persific only and used for ease of coding

And i think i'm right by what you chaps are saying - that -

msg1 db "This msg Box"

msg1 only excists in my asm file and not exec - and the string "This msg Box" when running is at location 0x00400000 + ( it's offset )

So below is an App that gets from the command line and msg box number of strings entered including app address..
it starts with format PE ..
when this is running - what part of this app would start at address space 0x00400000 ?
I'm also guessing again that format PE is fasm directive so wouldn't be included in the address space..??

Wot might help me better under stand the difference between assembler and executable - Is there an app i could write that would read the memory location from 0x00400000 to my apps limit and save the details into a file for futher study ?

I know memory is set in 8 bit chuncks - but to write a program to display whats in memroy i would need to know how big OR how much memory to read ?

if my .exe file is so many kb's then do i read that many in ?
I think the best thing to ask is when an .exe is loaded into memory ready for processing - is there a signiture at the very end of that apps adress space that i could use as a marker to so called end of file - but memory -
so i could stop reading in from there ?


i also know that windows allows each app 4 gig but i don't want to read that many .

Thanks people.



My main app
Code:
;Command line input
;Darren Ball
;28 November 2009
;main program that displays a msgbox with the number and values of parameters passed
;;;;;;;;;;;;;;;;;;
format PE GUI

include 'c:\fasm\include\win32a.inc'

section '.code' readable writeable

 start:
       pusha                      ;save all registers
      invoke GetCommandLine      ; Get command line parameters

        call  StrCount             ;Count the number of strings on the command line 1 = no values passed

        push eax                   ;save the string of command line parameters - maybe use more oneday ?
    xor eax, eax               ;clear the value inside eax register
     mov al, [cnt]              ; load eax with number of strings counted, cnt is global and is loaded from call strCount of strManip.inc
        call bcd2dec               ;convert string binary coded decimal to decimal
                             ;for this app would have been easier just to add [cnt], 48 -
                                ;but i wanted to make a conversion proc
                             ; The decimal value is now in 'decimal'


        cmp [cnt], 1                ;compare cnt so we know which msgbox to display
 je no_param               ;if '1' then only app address so no parameters were passed

  pop eax                    ;return the command line parameters just in case i wanted to use them


            invoke MessageBox, 0, eax, decimal, MB_OK   ;decimal is the structure created in bcd2dec.dec
                jmp exit



        no_param:
               invoke MessageBox, 0, Title, msg, MB_OK
    exit:                           ;return to all registers their initial values
    popa
        invoke ExitProcess         ;close this app

;section '.data' readable writeable

;Data section    section '.data' readable writeable causes errors ?
 buffer db 30 dup (' ')
 msg db 'No Command Line Parameters ? ', 0dh, 0ah, 0
 Title db "Parameters' Passed", 0
 cnt db 0,0   ; Extra null (0) to stop garbage being displayed



;Imported files

data import

library user32,'user32.dll', kernel32,'kernel32.dll'

include 'c:\fasm\include\api\user32.inc'
include 'c:\fasm\include\api\kernel32.inc'
include '%include%\bcd2dec.dec'
include "%include%\StrManip.inc"
end data
    





My inc file that counts how many units (Strings passed)
Code:
;String Manipulation
;Darren Ball
;28 november 2009


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; eax must have a value passed into it                      ;;
;; and a glabel variable named cnt must be setup in main prog;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


proc StrCount

  push ebx                   ;save value of ebx ...just incase
        mov ebx, eax
        mov [cnt], 1               ;GetCommandLine will always return if nothing else address of app

    loop1:
          cmp byte [ebx], '"'      ;test for quoted strings as these will be counted as 1 string
               je qloop
            cmp byte [ebx], ' '   ;each string counted will be seperated by spaces
            je  loop1next
               cmp byte [ebx], 0
           je loop1end
         inc ebx
             jmp loop1

       loop1next:
              add [cnt], 1       ;Add instead of inc , because inc moves along address space in mem ?
             inc ebx
             jmp loop1

       qloop:
          inc ebx            ;Ignore spaces inside of quotation marks
         cmp byte [ebx], '"'
          jne qloop
           inc ebx
             jmp loop1

       loop1end:
              pop ebx             ;return original value of ebx
    ret

endp
    




And finaly converting bcd to decimal - easier just to add [cnt], 48 but wanted to write a converter for future use
Code:

;Include file for printing decimal from binary-coded-decimal
;Darren Ball
;28 november 2009

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;CAUTION use EAX to pass bcd value;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

proc bcd2dec
        jmp bcd2dec_start   ;Skip over the data setup

struct decout               ;design a decimal holding table
        hunthou db 0
        tenthou db 0
        thou db 0
        hun db 0
        ten db 0
        unit db 0
        null db 0     ;not used - it's needed to stop the display of garbage data
ends

decimal decout       ;Create an instance of the structure decout

        ;;Test eax values now and loading relevant members of decimal table decout (decimal)
        bcd2dec_start:
        ;Decimal up to but not reacing 1 million
                 cmp eax, 0             ;Error if no value passed in eax
                 je bcd2dec_errorValue

                 cmp eax, 1000000
                 jge bcd2dec_errorMill
        bcd2dec_loop1:
                 cmp eax, 100000
                 jl bcd2dec_loop1end
                 add [decimal.hunthou], 1
                 sub eax, 100000
                 jmp bcd2dec_loop1
        bcd2dec_loop1end:
                 cmp eax, 10000
                 jl bcd2dec_loop2
                 add [decimal.tenthou], 1
                 sub eax, 10000
                 jmp bcd2dec_loop1
        bcd2dec_loop2:
                 cmp eax, 1000
                 jl bcd2dec_loop2end
                 add [decimal.thou], 1
                 sub eax, 1000
                 jmp bcd2dec_loop1
       bcd2dec_loop2end:
                 cmp eax, 100
                 jl bcd2dec_loop3
                 add [decimal.hun], 1
                 sub eax, 100
                 jmp bcd2dec_loop1
       bcd2dec_loop3:
                 cmp eax, 10
                 jl bcd2dec_loop3end
                 add [decimal.ten], 1
                 sub eax, 10
                 jmp bcd2dec_loop1
       bcd2dec_loop3end:
                 cmp eax, 0
                 jle bcd2dec_fin
                 add [decimal.unit], 1
                 sub eax, 1
                 jmp bcd2dec_loop1

        ;; Error messages - returned in eax 1 = no value, 2 = overflow
        bcd2dec_errorValue:
                 mov eax, 1
                 jmp bcd2dec_fin
        bcd2dec_errorMill:
                 mov eax, 2


        bcd2dec_fin:
                add [decimal.hunthou], 48
                add [decimal.tenthou], 48
                add [decimal.thou], 48
                add [decimal.hun], 48
                add [decimal.ten], 48
                add [decimal.unit], 48

                ;; Had to use loads of jmps here as 'if; statements wouldn't change values ????????
                ;; if decimal.hunthou = 48
                ;;        mov [decimal.hunthou], 32
                ;; end if
                ;; no value change ?
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;
       bcd2dec_Padd:
                cmp [decimal.hunthou], 48
                je hunthouPadd
       bcd2dec_Padd1:
                cmp [decimal.tenthou], 48
                je tenthouPadd
       bcd2dec_Padd2:
                cmp [decimal.thou], 48
                je thouPadd
       bcd2dec_Padd3:
                cmp [decimal.hun], 48
                je hunPadd
       bcd2dec_Padd4:
                cmp [decimal.ten], 48
                je tenPadd
                jmp bcd2dec_ret
        hunthouPadd:
                mov [decimal.hunthou], 32
                jmp bcd2dec_Padd1
        tenthouPadd:
                mov [decimal.tenthou], 32
                jmp bcd2dec_Padd2
        thouPadd:
                mov [decimal.thou], 32
                jmp bcd2dec_Padd3
        hunPadd:
                mov [decimal.hun], 32
                jmp bcd2dec_Padd4
        tenPadd:
                mov [decimal.ten], 32
                ;jmp bcd2dec_fin
        bcd2dec_ret:


        ret
endp     




    



Thanks again for your help chaps.
Post 29 Nov 2009, 13:46
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 29 Nov 2009, 19:32
DarrenBall wrote:
Wot might help me better under stand the difference between assembler and executable - Is there an app i could write that would read the memory location from 0x00400000 to my apps limit and save the details into a file for futher study ?
I think a disassembler/debugger is what you're looking for. An excellent free one is OllyDbg which I use all the time for debugging my apps. A debugger is like walking 1 step at a time through your app, stopping at any point you want to analyze the situation (registers, memory, etc etc) in that instant.

It's a great learning tool for this. Wink

@sinsi: you're correct, I'm sorry for my mistake. Smile

_________________
Previously known as The_Grey_Beast
Post 29 Nov 2009, 19:32
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.