This is probally a really stupid question but how do you call a memory address in ASM? I am using the code call dword 557054 (557054 is were code is located...) but I figure that it is calling 557054 + were ever the program got loaded into into memory. I need this for my executable loader...
There are two ways to do this, you can use CALL or you can use JMP, the second is more flexible but requires you to do a little more work if you want some compatibility with C-style code
Simple c-function call using CALL
push eax ; push args to stack
push ebx
call my_func ; my_func can be a c exported function or defined as a macro or asm function
Related
Each process is building some array and is writing this array in the "correct" place, using mpi_file_write_at().
After writing to the file I read from the same place and it is not what I wrote. The code is attached. I am just a beginner in MPI, so sorry if the question is not clever.
program output
use mpi
implicit none
integer :: ierr,i,proc_num,file,intsize
integer :: status(mpi_status_size)
integer,parameter :: count=10
integer,dimension(count) :: buf
integer,dimension(3*count) :: arr
integer(kind=mpi_offset_kind) :: disp
call mpi_init(ierr)
call mpi_comm_rank(MPI_COMM_WORLD,proc_num,ierr)
do i=1,count
buf(i) = proc_num*count+i
enddo
call mpi_file_open(MPI_COMM_WORLD,'out.txt',mpi_mode_wronly+mpi_mode_create,mpi_info_null,file,ierr)
call mpi_type_size(mpi_integer,intsize,ierr)
disp = proc_num*count*intsize
call mpi_file_write_at(file,disp,buf,count,mpi_integer,status,ierr)
if (proc_num==0) then
call mpi_file_read_at(file,0,arr,3*count,mpi_integer,status,ierr)
write(*,*),arr
endif
call mpi_file_close(file,ierr)
call mpi_finalize(ierr)
end program output
Thank you!
You are using mpi_mode_wronly to open the file. As stated here, it corresponds to "write only". Consequently, mpi_file_read_at() is likely to fail. It can be checked by looking at the output parameter ierr.
Could you try the mpi_mode_rdwr flag ? This should enable both read and write operations.
Moreover, MPI_File_write_at() is a noncollective operation. So process 0 can call mpi_file_read_at() before process 1 exited MPI_File_write_at(). A mpi_barrier() can be added to prevent that. Take a look at http://www.mpi-forum.org/docs/mpi-2.2/mpi22-report/node305.htm . It features various examples using MPI_File_write_at(). It is likely that additional calls to MPI_File_sync() and MPI_File_set_view() are required as well.
Notice that the code you provided is equivalent to a call to the function MPI_Gather().
I've seen that in libc.so the actual type of strcmp_sse to call is decided by the function strcmp itself.
Here it is the code:
strcmp:
.text:000000000007B9F0 cmp cs:__cpu_features.kind, 0
.text:000000000007B9F7 jnz short loc_7B9FE
.text:000000000007B9F9 call __init_cpu_features
.text:000000000007B9FE
.text:000000000007B9FE loc_7B9FE: ; CODE XREF: .text:000000000007B9F7j
.text:000000000007B9FE lea rax, __strcmp_sse2_unaligned
.text:000000000007BA05 test cs:__cpu_features.cpuid._eax, 10h
.text:000000000007BA0F jnz short locret_7BA2B
.text:000000000007BA11 lea rax, __strcmp_ssse3
.text:000000000007BA18 test cs:__cpu_features.cpuid._ecx, 200h
.text:000000000007BA22 jnz short locret_7BA2B
.text:000000000007BA24 lea rax, __strcmp_sse2
.text:000000000007BA2B
.text:000000000007BA2B locret_7BA2B: ; CODE XREF: .text:000000000007BA0Fj
.text:000000000007BA2B ; .text:000000000007BA22j
.text:000000000007BA2B retn
What I do not understand is that the address of the strcmp_sse function to call is placed in rax and never actually called. Therefore I am wondering: who is going do call *rax? When?
Linux dynamic linker supports a special symbol type called STT_GNU_IFUNC. Strcmp is likely implemented as an IFUNC. 'Regular' symbols in a dynamic library are nothing more but a mapping from a name to the address. IFUNCs are a bit more complex than that: the address isn't readily available, in order to obtain it the linker must execute a piece of code from the library itself. We are seeing an example of such a peice of code here. Note that in x86_64 ABI a function returns the result in RAX.
This technique is typically used to pick the optimal implementation based on the CPU features. Please note that the selection logic runs only once; all but the first call to strcmp are fast.
Ex : Function Implementation:
facto(x){
if(x==1){
return 1;
}
else{
return x*facto(x-1);
}
in more simple way lets take a stack -->
returns
|2(1)|----> 2(1) evaluates to 2
|3(2)|----> 3(2)<______________| evaluates to 6
|4(3)|----> 4(6)<______________| evaluates to 24
|5(4)|----> 5*(24)<____________| evaluates to 120
------ finally back to main...
when a function returns in reverse manner it never knows what exactly is behind it? The stack have activation records stored inside it but how they know about each other who is popped and who is on top?
How the stack keeps track of all variables within the function being
executed? Besides this, how it keeps track of what code is executed
(stackpointer)? When returning from a function call the result of that
function will be filled in a placeholder. By using the stackpointer
but how it knows where to continue executing code? These are the
basics of how the stack works I know but for recursion I don't
understand how it exactly works??
When a function returns its stack frame is discarded (i.e the complete local state is pop-ed out of the stack).
The details depend on the processor architecture and language.
Check the C calling conventions for x86 processors: http://en.wikipedia.org/wiki/X86_calling_conventions, http://en.wikibooks.org/wiki/X86_Disassembly/Functions_and_Stack_Frames and search for "PC Assembly Language" by Paul A. Carter (its a bit outdated but it has a good explanation of C and Pascal calling conventions for the ia32 architecture).
In C in x86 processors:
a. The calling function pushes the parameters of the called function to the stack in reverse order and then it pushes the pointer to the return address.
push -6
push 2
call add # pushes `end:` address an then jumps to `add:` (add(2, -6))
end:
# ...
b. Then the called function pushes the base of the stack (the ebp register in ia32) (it is used to reference local variables in the caller function).
add:
push ebp
c. The called function sets ebp to the current stack pointer (this ebp will be the reference to access the local variables and parameters of the current function instance).
add:
# ...
mov ebp, esp
d. The called function reserves space in the stack for the local (automatic) variables subtracting the size of the variables to the stack pointer.
add:
# ...
sub esp, 4 # Reserves 4 bytes for a variable
e. At the end of the called function it sets the stack pointer to be ebp (i.e frees its local variables), restores the ebp register of the caller function and returns to the return address (previously pushed by the caller).
add:
# ...
mov esp, ebp # frees local variables
pop ebp # restores old ebp
ret # pops `end:` and jumps there
f. Finally the caller adds to the stack pointer the space used by the parameters of the called function (i.e frees the space used by the arguments).
# ...
end:
add esp, 8
Return values (unless they are bigger than the register) are returned in the eax register.
I'm getting this unhandled exception when I exit my program:
Unhandled exception at 0x102fe274 (msvcr100d.dll) in Parameters.exe: 0xC0000005: Access violation reading location 0x00000005.
The debugger stops in a module called crtdll.c on this line:
onexitbegin_new = (_PVFV *) DecodePointer(__onexitbegin);
The top line on the call stack reads:
msvcr100d.dll!__clean_type_info_names_internal(__type_info_node * p_type_info_root_node=0x04a6506c) Line 359 + 0x3 bytes C++
The program then remains in memory until I close down the IDE.
I'm more used to developing with managed languages so I expect I'm doing something wrong with my code maintenance. The code itself reads a memory mapped file and assoiciates it with pointers:
SUBROUTINE READ_MMF ()
USE IFWIN
USE, INTRINSIC :: iso_c_binding
USE, INTRINSIC :: iso_fortran_env
INTEGER(HANDLE) file_mapping_handle
INTEGER(LPVOID) memory_location
TYPE(C_PTR) memory_location_cptr
INTEGER memory_size
INTEGER (HANDLE) file_map
CHARACTER(5) :: map_name
TYPE(C_PTR) :: cdata
integer :: n = 3
integer(4), POINTER :: A, C
real(8), POINTER :: B
TYPE STRUCT
integer(4) :: A
real(8) :: B
integer(4) :: C
END TYPE STRUCT
TYPE(STRUCT), pointer :: STRUCT_PTR
memory_size = 100000
map_name = 'myMMF'
file_map = CreateFileMapping(INVALID_HANDLE_VALUE,
+ NULL,
+ PAGE_READWRITE,
+ 0,
+ memory_size,
+ map_name // C_NULL_CHAR )
memory_location = MapViewOfFile(file_map,
+IOR(FILE_MAP_WRITE, FILE_MAP_READ),
+ 0, 0, 0 )
cdata = TRANSFER(memory_location, memory_location_cptr)
call c_f_pointer(cdata, STRUCT_PTR, [n])
A => STRUCT_PTR%A
B => STRUCT_PTR%B
C => STRUCT_PTR%C
RETURN
END
Am I supposed to deallocate the c-pointers when I'm finished with them? I looked into that but can't see how I do it in Fortran...
Thanks for any help!
The nature of the access violation (during runtime library cleanup) suggests that your program is corrupting memory in some way. There are a number of programming errors that can lead to that - and the error or errors responsible could be anywhere in your program. The usual "compile and run with all diagnostic and debugging options enabled" approach may help identify these.
That said, there is a programming error in the code example shown. The C_F_POINTER procedure from the ISO_C_BINDING intrinsic module can operate on either scalar or array Fortran pointers (the second argument). If the Fortran pointer is a scalar then the third "shape" argument must not be present (it must be present if the Fortran pointer is an array).
Your code breaks this requirement - the Fortran pointer STRUCT_PTR in your code is a scalar, but yet you provide the third shape argument (as [n]). It is quite plausible that this error will result in memory corruption - typically the implementation of C_F_POINTER would try and populate a descriptor in memory for the Fortran pointer, and the descriptor for a pointer to an array may be very different from a pointer to a scalar.
Subsequent references to STRUCT_PTR may further the corruption.
While it is not required by the standard to diagnose this situation, I am a little surprised that the compiler does not issue a diagnostic (assuming you example code is what you actually are compiling). If you reported this to your compiler's vendor (Intel, presumably given IFWIN etc) I suspect they would regard it as a deficiency in their compiler.
To release the memory associated with the file mapping you use the UnmapViewOfFile and CloseHandle API's. To use these you should "store" (your program needs to remember in some way) the base address (memory_location, which can also be obtained by calling C_LOC on STRUCT_PTR once the problem above is fixed) returned by MapViewOfFile, and the handle to the mapping (file_map) returned by CreateFileMapping; respectively.
I've only ever done this with Cray Pointers: not with the ISO bindings and I know it does work with Cray Pointers.
What you don't say is whether this is happening the first time or second time the routine is being called. If it is called more than once, then there is a problem in the coding in that Create/OpenFileMapping should only be called once to get a handle.
You don't need to deallocate memory because the memory is not yours to deallocate: you need to call UnmapViewOfFile(memory_location). After you have called this, memory_location, memory_location_cptr and possibly cdata are no longer valid.
The way this works is with two or more programs:
One program calls CreateFileMapping, the others calls OpenFileMapping to obtain a handle to the data. This only needs to be called once at the start of the program: not every time you need to access the file. Multiple calls to Create/OpenFileMapping without a corresponding close can cause crashes.
They then call MapViewOfFile to map the file into memory. Note that only one program can do this at a time. When the program is finished with the memory file, it calls UnmapViewOfFile. The other program can now get to the file. There is a blocking mechanism. If you do not call UnmapViewOfFile, other programs using MapViewOfFile will be blocked.
When all is done, call close on the handle created by Create/OpenFileMapping.
my program is as follows:
module x
use mpi !x includes mpi module
implicit none
...
contains
subroutine do_something_with_mpicommworld
!use mpi !uncommenting this makes a difference (****)
call MPI_...(MPI_COMM_WORLD,...,ierr)
end subroutine
...
end module x
program main
use mpi
use x
MPI_INIT(...)
call do_something_with_mpicommworld
end program main
This program fails with the following error: MPI_Cart_create(199): Invalid communicator, unless
the line marked with (**) is uncommented.
Now, maybe my knowledge of Fortran 90 is incomplete, but i thought if you have a use clause in the module definition (see my module x), whichever global variable exists in the included module (in case of x : MPI_COMM_WORLD from include module mpi) will have the same value in any of the contained subroutines ( do_something_with_mpicommworld ) even when those subroutines do not explicitly include the module (e.g. when (**) is commented out). Or, to put it simply, if you include a module within another module, the subroutines contained in the second module will have access to the globals in the included module without a special use statement.
When I ran my programme, I saw a different behaviour. The sub contained in x was creating errors unless it had the 'use mpi' statement.
So what is the problem, do I have a wrong idea about Fortran 90, or is there something special about MPI module which induces such behaviour?
Its annoyingly hard to find exact details about what should and shouldn't happen in these cases, and my expectation was the same as yours -- the `use mpi' should work as above. So I tried the following:
module hellompi
use mpi
implicit none
contains
subroutine hello
integer :: ierr, nprocs, rank
call MPI_INIT(ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
print *, 'Hello world, from ', rank, ' of ', nprocs
print *, MPI_COMM_WORLD
call MPI_FINALIZE(ierr)
return
end subroutine hello
end module hellompi
and it works fine under both gfortran and ifort with OpenMPI. Adding a cart_create doesn't change anything.
What strikes me as weird with your case is that it isn't complaining that MPI_COMM_WORLD isn't defined -- so obviously some of the relevant information is being propagated to the subroutine. Can you post a simpler full example which still fails to work?
Thank you Johnatan for your answer. The problem was really, really simple. I added the subroutine in question after the "end module"
:-D, 'implicit none' did not apply to now external sub and compiler happily initialised a brand new variable MPI_COMM_WORLD to whatever it thought suitable following the standard implicit rules.
This is just a lesson to me to enforce 'implicit none' not only by keywords, but also via the compiler flag. Evil lurks after every end statement.
I'm sorry you went trough the trouble of making the test example, I'd buy you a beer if I could :-)