如何用NASM汇编写一个静态资源服务器?(六)、终章,启动参数
前言
我们已经完成了一个基本的http服务器,但是端口和root路径是写死的,如果需要更改,还的重新编译,那么,我们可以利用启动参数来动态绑定,解决这个问题。
比如最终我们可以用下面方式启动的程序。
./socket 7070 /home/www/
启动参数也是放在栈中的,从esp开始的第一个4字节表示参数个数,如果什么也不传,则是1,因为默认会有一个参数是程序的启动路径,从偏移12个字节开始,是我们传递的参数,为什么是偏移12而不是8呢?因为我们的程序从单独的方法中加载参数,调用方法时,会把返回地址也压入栈,当ret时候会弹出,所以,会偏移12字节。
注意这里表示参数是一个字符指针。
完整程序地址:https://github.com/houxinlin/nasm-examples/tree/main/http-server
加载端口
这个函数用来加载端口号,需要把ascii转换int,还有就是需要反转,因为在bind函数调用时,端口需要反序存储,调用toInt后会把端口号转换为int并且放入eax中,然后把eax的低8位放入ebx的高8位,eax的高8位放入ebx的低8位。
loadBindPort:
mov esi,[esp+12] ;;从启动参数中加载端口
call reversal ;;反转端口字节
ret
reversal:
call toInt
mov ebx,0
mov bh,al
mov bl,ah
ret
toInt:
mov eax,0
mov ecx,0
_nextToInt:
cmp byte[esi+ecx],0
je _finishToInt
mov edx,0
mov dl, [esi+ecx]
sub dl,48 ;;edx中保存当前ascii转换的数组
push edx
mov ebx,10
mul ebx
pop edx
add eax,edx
inc ecx
jmp _nextToInt
_finishToInt:
ret
加载root路径
loadBindRoot比较简单,首先获取第二个参数长度,然后通过movsb复制到root变量中即可。
loadBindRoot:
mov esi ,[esp+16]
call getStringLength
mov ecx,eax
mov edi,root
rep movsb
ret
然后在主程序中调用即可
CMAIN:
xor eax, eax
xor ebx, ebx
xor edi, edi
xor esi, esi
;push default_path
;push default_port
;push default_media
;push 3
call loadBindPort
mov dword[port],ebx
call loadBindRoot
- END -
原文始发于微信公众号(十四个字节):如何用NASM汇编写一个静态资源服务器?(六)、终章,启动参数