Manual Null-Termination on Unix using Intel x86 Assembly (address vs value in memory operands)? -
i have missing obvious here, can't seem find end of string.
my code starts off few calls read follows:
; read user input ; mov eax, syscall_read ; read function mov ebx, stdin ; arg 1: file descriptor mov ecx, buf ; arg 2: address of buffer (buffer input) mov edx, buflen ; arg 3: buffer length (defined 256) int 080h mov [rlen], eax ; save length of string read
the professor gave shell program work from, i've got pretty handle on of it. what's throwing me off of impression rlen should contain length of string i'm using, when type following:
mov byte[esi + rlen], 92 ; add 0
i segfault. same, also, if use [buf + rlen]. neither buf nor esi on own cause segfault, seems me rlen isn't doing think is.
anyone able me figure out what's going on?
two problems code:
mov byte[esi + rlen], 92
92 != 0
. terminating 0 byte,'\0'
, integer value zero.rlen address, not value @ address.
so test read returned >= 0, use return value that's still in register.
; read(2) return value still in eax test eax, eax jl read_error ; handle errors on eax less zero. mov esi, buf ; mov imm32 address in register mov [rlen], eax ; store return value rlen global mov byte ptr[esi + eax], 0 ;or: mov byte ptr [buf + eax], 0 ; works because buffer statically allocated. jz handle_eof ; flags still set test
or if copied ecx register that's not clobbered read system call, can use instead of reloading.
within function, think of local variables living in registers, , memory locations somewhere can spill them if run low on registers. don't non-optimizing compiler , store/reload variables when don't need to. easier on architecture x86-64 16 regs; 32bit x86 pretty badly limited, , has obsolete args-on-the-stack abi.
if buffer zeroed, pass read(2) count 1 smaller buffer size. zeroing last byte after read returns better, though.
Comments
Post a Comment