Пример функции преобразования адреса из вида XXX.XXX.XXX.XXX на ассемблере:
.MODEL LARGE, C
Addr STRUC
OFFS DW 0
SEGM DW 0
Addr ENDS
PARSE_ADDRESS EQU 50h
.CODE
PUBLIC C NetParseAddress
SockAddr Addr ?
; --------------------------------------
; Функция преобразования сетевого адреса
;
; DWORD NetParseAddress(char* str)
; --------------------------------------
;
NetParseAddress PROC
ARG str: DWORD
push ds
mov ah, PARSE_ADDRESS
mov dx, WORD PTR str
mov ds, WORD PTR str+2
pushf
call DWORD PTR cs:[SockAddr]
pop ds
ret
NetParseAddress ENDP
Процесс получения адреса вызова Sockets API (cs:[SockAddr]) в примере на ассемблере (как и в примере на С) не рассматривается, поскольку требует более тщательного описания процесса доступа к функциям API. Возможно, это будет сделано позже, на примере одной из конкретных программ.
А вот пример аналогичной функции на С и функции получения адреса через доменное имя:
#define PARSE_ADDRESS 0x50
#define RESOLVE_NAME 0x54
// ---------------------------------------
int CallApi(X86Regs* px86regs) {
union REGS r;
struct SREGS s;
// сброс ошибок
iNetErrNo = iNetSubErrNo = 0;
// вызов функции API
r.x.ax = px86regs->ax;
r.x.bx = px86regs->bx;
r.x.cx = px86regs->cx;
r.x.dx = px86regs->dx;
r.x.si = px86regs->si;
r.x.di = px86regs->di;
s.ds = px86regs->ds;
s.es = px86regs->es;
int86x(iSocketsApi, &r, &r, &s);
px86regs->ds = s.ds;
px86regs->es = s.es;
px86regs->ax = r.x.ax;
px86regs->bx = r.x.bx;
px86regs->cx = r.x.cx;
px86regs->dx = r.x.dx;
px86regs->si = r.x.si;
px86regs->di = r.x.di;
// проверка на ошибки
if(r.x.cflag != 0) {
iNetErrNo = px86regs->ax & 0x00ff;
iNetSubErrNo = px86regs->ax >> 8;
return -1; }
else return px86regs->ax;
}
// -----------------------------------------------------------------------
DWORD ParseAddress(char* pszName) {
X86Regs r;
r.ds = REALMODE_SEGMENT(pszName);
r.dx = REALMODE_OFFSET(pszName);
r.ax = PARSE_ADDRESS << 8;
if(CallApi(&r) == -1) return 0L;
else return (((DWORD) r.dx << 16L) + r.ax);
}
// -----------------------------------------------------------------------
DWORD ResolveName(char* pszName, char* pcCname, int iCnameLen) {
X86Regs r;
r.ds = REALMODE_SEGMENT(pszName);
r.dx = REALMODE_OFFSET(pszName);
r.es = REALMODE_SEGMENT(pcCname);
r.di = REALMODE_OFFSET(pcCname);
r.cx = iCnameLen;
r.ax = RESOLVE_NAME << 8;
if(CallApi(&r) == -1) return 0L;
else return (((DWORD) r.dx << 16L) + r.ax);
}
В примере:
CallApi - функция доступа к Sockets API,
ParseAddress - функция преобразования адреса вида XXX.XXX.XXX.XXX,
ResolveName - соответственно получение адреса через сервер доменных имен.