//----------------------------------------------------------------- // asclient.s // // This is an assembly language implementation of the socket // system-calls used in our 'udpclient.cpp' application; but // note that the server's IP-address and its port-number are // are 'hard-coded' into this program's data section (UGH!). // So it's up to you to 'enhance' this program so that users // can supply those values as command-line argument-strings. // // assemble using: $ as asclient.s -o asclient.o // and link using: $ ld asclient.o -o asclient // // programmer: ALLAN CRUSE // written on: 09 MAR 2008 //----------------------------------------------------------------- # manifest constants .equ sys_exit, 1 # from .equ sys_write, 4 .equ sys_socketcall, 102 .equ SYS_SOCKET, 1 # from .equ SYS_BIND, 2 .equ SYS_SENDTO, 11 .equ SYS_RECVFROM, 12 .equ SYS_RECV, 10 .equ STDOUT, 1 # from .equ PF_INET, 2 # from .equ SOCK_DGRAM, 2 # from .equ IPPROTO_UDP, 17 # from .section .data # the message-text to be transmitted data: .asciz "The sea is calm tonight, the tide is full...\n" dlen: .int . - data # length of datagram's data # our buffer for the server's reply buf: .space 1500 # buffer for received packet len: .int . - buf # size of the receive buffer # the array for the socketcall parameters args: .int PF_INET, SOCK_DGRAM, IPPROTO_UDP, 0, 0, 0, 0, 0 # the 'sock_address' data-structure addr: .short PF_INET # ID for the protocol-family port: .short 32795 # the server's port-number .byte 138, 202, 171, 58 # the server's IP-address .space 8 # padding for structure-size alen: .int 16 # variable needed for length # miscellaneous data sock: .int -1 # place to put socket's ID .section .text _start: # create the socket using preinitialized arguments mov $sys_socketcall, %eax # system-call ID-number mov $SYS_SOCKET, %ebx # subfunction ID-number lea args, %ecx # pointer to arguments int $0x80 # invoke kernel service mov %eax, sock # save socket's handle # prepare argument-array for our 'sendto' system-call mov sock, %eax mov %eax, args+0 # sock lea data, %eax mov %eax, args+4 # &data mov dlen, %eax mov %eax, args+8 # dlen movl $0, args+12 # flags movl $addr, args+16 # &addr mov alen, %eax mov %eax, args+20 # alen rolw $8, port # swap bytes (for network-order) # invoke system-sall to transmit our datagram mov $sys_socketcall, %eax # system-call ID-number mov $SYS_SENDTO, %ebx # subfunction ID-number lea args, %ecx # pointer to arguments int $0x80 # invoke kernel service # now marshall the arguments needed for 'recvfrom' mov sock, %eax mov %eax, args+0 # sock movl $buf, args+4 # &buf mov len, %eax mov %eax, args+8 # len movl $0, args+12 # flags # invoke system-call to receive server's reply mov $sys_socketcall, %eax # system-call ID-number mov $SYS_RECV, %ebx # subfunction ID-number lea args, %ecx # pointer to arguments int $0x80 # invoke kernel service mov %eax, len # save message's length # display the datagram received from the server mov $sys_write, %eax # system-call ID-number mov $STDOUT, %ebx # device-file ID-number lea buf, %ecx # pointer to message mov len, %edx # length of message int $0x80 # invoke kernel service # terminate this program mov $sys_exit, %eax # system-call ID-number xor %ebx, %ebx # use zero as exit-code int $0x80 # invoke kernel service .global _start # make entry-point visible .end # nothing else to assemble