1. mmap.s:
#參考自"http://asm.sourceforge.net/articles/linasm.html"
.include "defines.h"
#A program can be divided into sections:
#.text for your code (read-only),
#.data for your data (read-write),
#.bss for uninitialized data (read-write);
#
#there can actually be a few other standard sections,
#as well as some user-defined sections, but there's
#rare need to use them and they are out of our interest here.
#
#A program must have at least .text section.
.data
fd:
.long 0
fdlen:
.long 0
mappedptr:
.long 0
.text
.globl _start
_start:
subl $24,%esp #to arrange args on the stack. without
#push/pops
#
#For all syscalls, the syscall number goes in %eax.
#For syscalls that have less than six args,
#the args go in %ebx,%ecx,%edx,%esi,%edi in order.
#The return value of the syscall is stored in %eax.
#
# open($file, $O_RDONLY);
movl $SYS_open,%eax
movl 32(%esp),%ebx # argv[1] is at %esp+8+24
xorl %ecx,%ecx # set %ecx to O_RDONLY, which = 0
int $0x80
test %eax,%eax # if return value < 0, exit
js exit
movl %eax,fd # save fd
# lseek($fd,0,$SEEK_END);
movl fd,%ebx
xorl %ecx,%ecx # set offset to 0
movl $SEEK_END,%edx
movl $SYS_lseek,%eax
int $0x80
movl %eax,fdlen # save file length
#
# Syscalls whos number of args is greater than five still
# expect the syscall number to be in %eax, but the args are
# arranged in memory and the pointer to the first arg is stored in %ebx.
#
# If you are using the stack, args must be pushed onto it backwards,
# i.e. from the last arg to the first arg. Then the stack pointer
# should be copied to %ebx. Otherwise copy args to an allocated area
# of memory and store the address of the first arg in %ebx.
#
# 所以依據上一段英文文字我們先知道stack layout 應該是:
# |NULL |<- SP (Stack Point)
# |$fdlen |
# |PROT_READ |
# |MAP_SHARED|
# |$fd |
# |0 |
#
# 而在X86機器上, 執行時的stack是往下長的(高位址往低位址長), heap則是往上長的
# 所以stack memory layout 應該是:
#
#
# 00000000 | |
# ... | |
# %esp |NULL |<- SP (Stack Point)
# %esp+4 |$fdlen |
# %esp+8 |PROT_READ |
# %esp+12 |MAP_SHARED|
# %esp+16 |$fd |
# %esp+20 |0 |
# .... | |
# ffffffff | |
#
# mmap(NULL,$fdlen,PROT_READ,MAP_SHARED,$fd,0);
#
xorl %edx,%edx
movl %edx,(%esp)
movl %eax,4(%esp)
movl $PROT_READ,8(%esp)
movl $MAP_SHARED,12(%esp)
movl fd,%eax
movl %eax,16(%esp)
movl %edx,20(%esp)
movl $SYS_mmap,%eax
movl %esp,%ebx
int $0x80
movl %eax,mappedptr # save ptr
# write($STDOUT, $mappedptr, $fdlen);
movl $STDOUT,%ebx
movl mappedptr,%ecx
movl fdlen,%edx
movl $SYS_write,%eax
int $0x80
# munmap($mappedptr, $fdlen);
movl mappedptr,%ebx
movl fdlen,%ecx
movl $SYS_munmap,%eax
int $0x80
# close($fd);
movl fd,%ebx # load file descriptor
movl $SYS_close,%eax
int $0x80
exit:
# exit(0);
movl $SYS_exit,%eax
xorl %ebx,%ebx
int $0x80
ret
2. defines.h:
SYS_exit = 1
SYS_fork = 2
SYS_write = 4
SYS_open = 5
SYS_close = 6
SYS_execve = 11
SYS_lseek = 19
SYS_dup2 = 63
SYS_mmap = 90
SYS_munmap = 91
SYS_socketcall = 102
SYS_socketcall_socket = 1
SYS_socketcall_bind = 2
SYS_socketcall_listen = 4
SYS_socketcall_accept = 5
SEEK_END = 2
PROT_READ = 1
MAP_SHARED = 1
AF_INET = 2
SOCK_STREAM = 1
IPPROTO_TCP = 6
STDOUT = 1
3. compile and execute:
gcc -c mmap.s
ld -s -o mmap mmap.o
./mmap mmap.s
沒有留言:
張貼留言