Author Topic: Some example of memory mapping files and related things?  (Read 16387 times)

Offline dalfonso01

  • Jr. Member
  • *
  • Posts: 44
Some example of memory mapping files and related things?
« on: May 29, 2014, 01:49:13 PM »
Hi,
I am looking at a sequel for my path and as I wrote elsewhere I do not want to migrate to use C library until it will be a voluntary choice.

I would at least be able to manage all the stuff related to files, being able to get, change and write back without tricks, "< >" or temp files or secondary names. At most I found something to open a file and display something to stdout, but I see there some new needs related to mmap for the more than 5 arguments and about the 90 91 sys_calls.

Is it possible that there is no coverage in Intel / NASM mnemonics ? I still see only the chap 16 of Wrox book, in AT&T / gas syntax and conventions.

Is that possible?

Thanks
Fabio D'Alfonso
« Last Edit: May 29, 2014, 01:52:56 PM by dalfonso01 »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Some example of memory mapping files and related things?
« Reply #1 on: May 29, 2014, 07:12:20 PM »
Hi Fabio,

ANYTHING is possible. I have learned not to rule anything out.

I am but an "experienced beginner" so I don't know where the "intermediate" or "advanced" path leads. I have an idea that the things you want to learn are "OS issues" rather than "Intel issues" or "Nasm issues". As such, you may need to read books on "Programming for Linux" or whatever directed to C (or worse) and "translate" to asm.

I'm pretty sure I have examples of mmap. The only thing I can find at the moment us mmaptest.s - yes, in the accursed AT&T syntax (probably the same thing you've got from Wrox?). I know you don't want t get into that quite yet. I can translate this to Nasm (I'm pretty sure)... but not right now (I'm even more distracted than usual lately). If I don't get back to you with more examples, or at least a translation of this one, feel free to remind me.

Later,
Frank

Code: [Select]
.section .data
.comm mmap_, 24

.section .text
.globl _start
_start:
#mmap_ is a struct which holds parameters for mmap kernel call
movl $0, mmap_    # I don't have preferences, just need memory somewhere
movl $64, mmap_+4  # length of requested memory
movl $3, mmap_+8      # read, write, PROT_WRITE | PROT_READ, 0x02, 0x01

# error left in to demonstrate "error handler" :)
movl $0x20, mmap_+12  # map anonymously

# movl $0x21, mmap_+12  # map anonymously | MAP_SHARED
# thanks, Chuck!

movl $-1, mmap_+16   # fd, -1 for portability
movl $0, mmap_+20    # offset is ignored

movl $90, %eax        # mmap number of syscall
lea mmap_, %ebx    #loading address of struct to %ebx
int $0x80                   # syscall
cmpl $0xFFFFF000, %eax
ja error

movl %eax, %edx  # probably result of syscall is in %eax
movl $0, (%edx)      #testing memory we got... this falls in segfault

xorl %eax, %eax  # claim no error

exit:
movl %eax, %ebx  #code
movl $1, %eax    #exit
int $0x80

# fancy error handler
error:
negl %eax
jmp exit

Offline dalfonso01

  • Jr. Member
  • *
  • Posts: 44
Re: Some example of memory mapping files and related things?
« Reply #2 on: May 29, 2014, 08:17:41 PM »
Hi,
thanks for the answer.

I would just go on as far as possible to manage some coding only in native nasm mnemonics, delaying any facility when it will be , then, a facility not a shortcut or better to say, a commodity.

I am not really interested in Linux, in this questions, but I am  interested in being, as told, able to build some tool in pure assembly, namely, I am planning a first iteration of a nasm formatter.
I can make a toy v0.1 using stdin / stdout or open a file and then write to stdout on another file, but a decent solution is at least to make in assembly what a C/C++ would make: load a .asmrc in memory, with options, take a file or a folder *.asm make mmap for source(s) file, modify in memory and then write back to the same file with unmap.

So I ended to mmap / and sys_calls 90 / 91 (or any other sys_call I will consider) as related to instrument my baggage, no for itself.

>>>The strange thing about assembly I am finding, is this temptation I see at various levels to leave native assembly as soon as possible, in favor of C both as inline asm and assembly written in C calling convention.
Something like "Ok, we played here and there a little, but was just for fun, now let's go to work and that requires some real solution", and before putting together a complete baggage, start to see  "call printf"  and brothers.

I find this quite misleading. >>No one is interested in native assembly for real problems as far as possible (book writers included)? This is what I pursuing, and I do not intend to use C library to do something (especially if in the  a,b,c of needs) unless I know how it can be done without.

Thanks
Fabio D'Alfonso







« Last Edit: May 29, 2014, 08:24:02 PM by dalfonso01 »

Offline dalfonso01

  • Jr. Member
  • *
  • Posts: 44
Re: Some example of memory mapping files and related things?
« Reply #3 on: May 30, 2014, 08:58:58 AM »
Hi,
started to make some experiment before the things vanish. This could be the worst stuff you could have ever seen, and will see, but I want to learn and so show you to ask for help

Unfortunately books on NASM end when the deal starts and no one will have a dinner (only) playing with lookup tables.

Making some search I found this:
1 - open a file
2 - get the filehandle
2 - calculate size of the file
3 - put in ebx a pointer to a struct containing the 6 parameters for mmap, among them the size and the filehandle from the open
4 - int 80h for sys_call 90 to memory map the file
5 - get the memory location of the mapped file

6 - make changes using the mappedfile

8 - munmap , that will itself write the file back.


About the parameters I find the suggestion to use a struct like this:

mmap_args:  ;
     .addr:     dd 0
     .len:       dd 512
     .prot:     dd 3
     .flags:     dd 34
     .fd:        dd -1
     .offset:   dd 0


where I should put the filehandle in .fd before the syscall

Open file, something like this:

; Get our command line arguments.
         nop
         nop
         pop ebx ; argc
         pop ebx ; argv[0] (executable name)
         pop ebx ; argv[1] (desired file name)
         mov eax, 5 ; syscall number for open
         xor ecx, ecx ; O_RDONLY = 0
         xor edx, edx ; Mode is ignored when O_CREAT isn't specified
         int 80h ; Call the kernel
         test eax, eax ; Check the output of open()
THIS is what I would do to pass the filehandle , but it is probably wrong         
         mov [mmap_args.fd],eax
         jns file_read ; If the sign flag is set (positive) we can
         ; begin reading the file
 ; If the output is negative, then open failed. So we should exit
 exit:
         mov eax, 1 ; 0x01 = syscall for exit
         xor ebx, ebx ; makes ebx technically set to zero
         int 80h

About the file size I found a suggestion to use llseek (sys_call 140), but could I set a fixed value meanwhile to contain the file or a part of it in memory?

after made some change in the mapped, this should munmap the file writing back.


  ;unmap
         mov eax,91
         mov ebx, mappedfile
         mov ecx, size
         int 80h

What seems to me roughly running this is that the .fd does not contain the filehandle and so nothing happens in the test file.

Thanks
Fabio D'Alfonso
« Last Edit: May 30, 2014, 09:04:59 AM by dalfonso01 »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Some example of memory mapping files and related things?
« Reply #4 on: May 30, 2014, 05:06:42 PM »
That looks roughly right. If the file handle isn't in mmap_args.fd that's a problem we'll have to investigate. You open the file O_RDONLY. That may prevent us from altering the file with mmap - I'm not sure. I'd try read-write. There's a "synch" command. We may need to use that to update the file, or perhaps just munmap will do it. I've only experimented a little with mmap, and I forget the results.

One again I'm going to have to put you off 'til "later". Do you do Usenet at all? If so, the group alt.lang.asm has a bunch of whining about how my life has been going. comp.lang.asm.x86 is also interesting. I'll pull myself together (I think) but in the meantime I'm less helpful than usual. Sorry.

Best,
Frank


Offline Gunner

  • Jr. Member
  • *
  • Posts: 74
  • Country: us
    • Gunners Software
Re: Some example of memory mapping files and related things?
« Reply #5 on: May 31, 2014, 02:21:01 AM »
Ok, your learning Assembly; let's start off on the right foot - Stop using "Magic Numbers"!!!!  Use the names of the sys calls and any other numbers!  It makes looking through your source code much easier, I can look at code and know exactly what the int 80h call does if you do
Code: [Select]
mov eax, sys_mmap instead of
Code: [Select]
mov eax, 90
I don't do 32 bit any more, so I had to get the brain working and convert some 64 bit code.  Here is a working example of sys_mmap:

Offline dalfonso01

  • Jr. Member
  • *
  • Posts: 44
Re: Some example of memory mapping files and related things?
« Reply #6 on: May 31, 2014, 05:48:20 AM »
Hi,
thanks, I succeded to correct the mmap code, but still have a doubt on one thing, but still want to figure by me, before asking on the forum. I will see your example after (thanks for putting in archive I cannot see....on my screen, directly).

Thanks also for the suggestion, I am still tailoring the habits around the code, and while going on, add and modify snippets / comments standards and others and so on to get consistent  'commented', 'readable'  code.

I am in the chicken /egg phase of the business: need to write to understand how to write better "memories", but the cycle is going fast.

Thanks
Fabio D'Alfonso
« Last Edit: May 31, 2014, 05:53:17 AM by dalfonso01 »

Offline dalfonso01

  • Jr. Member
  • *
  • Posts: 44
Re: Some example of memory mapping files and related things? found
« Reply #7 on: May 31, 2014, 06:55:31 AM »
Hi,
the rumination point is this:the prototype of mmap is this:

void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);

At the end of the mmap procedure the mov [mappedfile],eax , mappedfile should contain the memory location of the mapped file, i.e. the starting point to address its content in memory, as the initial address of Buffer where I could load a file.
Is that right?

I ask because I can use [mappedfile] as argument for sys_write getting the a LEN part of the mmap on stdout, so the handler is also the address of the location in Hex?

The post started as a question and ended as an answer (perhaps).

I was stuck on the new indirection level needed, so could not immediately get access to the content of the mapped file [mappedfile + ecx] would change the handler, is not an offset in the mapped content, this are the very first "hands in jam" programs, and some comes up for the first time.

After some rumination, realized that moving the content of mappedfile, in a register, would have produced a way use the content in effective address calculation and so:
   

Buffer resb 4 > ecx Buff  (in sys_write) 
while
mappedfile resb 4 (+mmap 90 sys_call)  > ecx [mappedfile] (in sys_write)

Code: [Select]
; mappedfile contains the address so we need to estract in a register to use
; dereference again to get its content in effective address calculation
        mov ebp,[mappedfile]

change: mov byte [ebp+2+edx],'3'
        dec edx
        jnz change


make the job.

What is missing here a calculation of the size, that is set up. I will make also that and update the code.

Code: [Select]
                                                 

section .bss

mappedfile: resb 4

section .data

mmap_args:
    .addr:   dd 0
    .len:    dd 512
    .prot:   dd 3
    .flags:  dd 1
    .fd:     dd -1
    .offset: dd 0

section .text
;-------------------------------------------------------------------------
; FileSize: Calculates the size of a file.
; UPDATED: 2014-05-30
; IN:
; RETURNS:
; MODIFIES:
; CALLS:
; DESCRIPTION: Calculate the size of file for mmap 
;

FileSize:
        mov eax,140
        mov ebp,ebx
        mov ecx,0
        mov edx,0
        lea esi,[ebp-8]
        mov edi,2
        int 80h
        mov eax,[ebp-8]
        ret

global _start

        _start:
; open(char *path, int flags, mode_t mode);

; Get our command line arguments.
        nop
        nop
        pop ebx ; argc
        pop ebx ; argv[0] (executable name)
        pop ebx ; argv[1] (desired file name)
        mov eax, 5 ; syscall number for open
        mov ecx, 0102 ; O_RDONLY = 0
        mov edx, 0644 ; Mode is ignored when O_CREAT isn't specified
        int 80h ; Call the kernel
        test eax, eax ; Check the output of open()
        js BadFile
        mov [mmap_args.fd],eax
        ; begin reading the file

; mmap
        mov eax,90 ; set the system call value
        lea ebx,[mmap_args]
        int 80h
        test eax,eax
        js BadFile
        add esp,24
        ;store the memory location of the memory mapped file
        mov [mappedfile],eax
       


; Operation on files
        mov edx,5

; mappedfile contains the address so we need to estract in a register to use
; dereference again to get its content in effective address calculation
        mov ebp,[mappedfile]

change: mov byte [ebp+2+edx],'3'
        dec edx
        jnz change


        mov eax,4
        mov ebx,1
        mov ecx, [mappedfile]
        mov edx,30
        int 80h
       




;unmap
        mov eax,91
        mov ebx, [mappedfile]
        mov ecx,[mmap_args.len]
        int 80h
        test eax,eax
        js BadFile

; close the open file handle
        mov eax,6
        mov ebx,[mmap_args.fd]
        int 80h
exit:
        mov eax, 1 ; 1 = syscall for exit
        xor ebx, ebx ; makes ebx technically set to zero
        int 80h
BadFile:
        mov ebx,eax
        mov eax,1
        int 80h

Thanks
Fabio D'Alfonso
« Last Edit: May 31, 2014, 08:32:23 AM by dalfonso01 »