Re: which book to start with...?
- From: naunetr <wildgoosechase@xxxxxxxxxxxxxxxxxxxxx>
- Date: Thu, 06 Dec 2007 17:18:53 +0530
Frank Kotler wrote:
naunetr wrote:Herbert Kleebauer wrote:
...ok. but your script doesnt look like nasm like given in Duntemann's book.
No? :)
Herbert finds Intel syntax (or Nasm's "Intel-like" syntax) illogical, confusing, and generally distasteful to use. So he uses a "homemade", 68k-like syntax. His assembler, "Lindela" assembles it directly. He has provided, for Nasm users, a set of Macros that approximates his preferred syntax.
at first i thought it was gas. but after seeing PGU i knew it was something else.
but i compiled it anyway. had to set executable bit to make it work,
Yup. Nasm doesn't know to set the executable bit. "Normally", Nasm's output would be a linkable object file, which just needs to be readable by ld - ld sets the executable bit on the executable...
will Herbert's elf header still work when linking several object files to form the executable?
but it works great. amazing only 248 bytes. the c prog i wrote to duplicate this was ~4kb!
Yup. Look how much more "productive" C was! :)
when syscall macro is used instead of fread size of c executable is down to 2928 bytes, 4 times bigger than asm version. :)
; nasm -O99 -f bin -o d2u d2u.asm
%include "mac.inc" ; ftp://137.193.64.130/pub/assembler/xlinux.zip
;===========================================================================
seg 32
orig equ $08048000
code_addr equ orig
code_offset equ 0
section .text vstart=code_addr
;--------------------------- ELF header -----------------------------------
dc.l $464c457f,$00010101,0,0,$00030002,1,main,$34,0,0,$00200034,2,0
dc.l 1,code_offset,code_addr,code_addr,code_filez,code_memsz,5,4096
dc.l 1,data_offset,data_addr,data_addr,data_filez,data_memsz,6,4096
;--------------------------- code ------------------------------------------
wow. all this is totally above my leval of understanding guys.
And that's just the ELF header! Herbert feels that every byte that appears in the executable ought to be accounted for in the source code.
i guess thats possible only in machine code?
In general, I agree, but I'm willing to let ld add the "OS cruft", so long as it doesn't touch my actual executable code. I like Herbert's method - it's smaller than what I can get get out of ld, and I like "small".
still when c library is called instead of read syscall the size becomes many times more. and my java app for the same thing is only 447 bytes but at runtime it takes 200Mb of memory!!
One of the many things on my "todo" list is a fully-commented "version" of that ELF header, showing what each byte means, and what the alternatives might be. There's also code around - Chuck posted a version for Fasm and Nasm a while ago - that *reads* the ELF header, and displays what it finds. (similar to objdump or elfdump) If you want to get into the details of the ELF header, it's all documented. Start here, perhaps...
<http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html>
There's a famous comment in the Linux code: "/* you are not expected to understand this */". You can take that approach for now, if you want. It's the executable header, 'nuff said. :)
yes Frank. i'll save that link but maybe a bit later after i understand some basic assembly.
I've "translated" Herbert's code back to "regular Nasm", and let ld do the job of creating the header. Substantially larger (440 bytes, after "strip -R.comment d2u"), but perhaps "easier to read" (for who? Herbert liked it the way it was!)
I guess you understand that this is to be used as a "filter" - "d2u<dosfile.txt>unixfile.txt"... This version is assembled with "nasm -f elf d2u.asm", and linked with "ld -o d2u d2u.o". There are options - using the "-s" switch to ld will create a smaller file - doing "strip -R.comment d2u" will make it smaller still (and you can skip "-s"). (Nasm users who are unaware of it will probably be appalled to find that Nasm puts its name in a .comment section...).
i saw that when i looked at the executable in vim's hex viewer. i think the 0.98.39 version didn't do this?
is there any chace that strip can damage execute or object files or is it always safe to use even with s option?
also noticed that even strip -s doesnt remove the nasm comment from readc. so nasm creates a separate .comment section? what if users code already has a .comment section? nasm adds to it? ;)
If you have questions about how it works, just ask... Herbert! :)
Best,
Frank
global _start
section .text
_start:
top:
call getc
cmp eax, byte -1 ; this is our end-of-file indicator
je good_exit
cmp al, 13 ; we're skipping carriage-returns
je top
call putc ; output everything else
jmp short top
good_exit:
mov ebx, 0
mov eax, 1
int 0x80
;----------------
getc:
pushad ; save caller's regs
mov ebx, 0 ; stdin
mov ecx, buf ; address of buffer
mov edx, 1 ; count
mov eax, 3 ; __NR_read
int 0x80
test eax, eax ; this just sets the flags
okay i have look this instruction up. i only cmp for now.
nasm manual says test does a bitwise and of its operands and affects the "flags". so this would do an and with identical values.
js getc_error ; if negative, something bad happened
nasm manual says this jumps to operand when sign flag is set. but i dont understand how the previous test will set the sign flag. never mind, i guess PGU explains this sort of stuff...
popad ; restore caller's regs
jz nothing_read ; if eax is zero, end-of-file
movzx eax, byte [buf] ; get our character in al/eax
ret ; return to caller
nothing_read:
or eax, byte -1 ; same as "mov eax, -1", but shorter
but my c book says that end of file is normal so shouldnt we return zero instead of -1? also shouldn't popad be just before the ret under nothing_read?
ret ; return our end-of-file marker
getc_error: ; unlikely, but if error reading stdin
or ebx, byte -1 ; set an exit code, and bail out
mov eax, 1 ; __NR_exit
int 0x80
;----------------------
putc:
pushad ; save caller's regs
mov ebx, 1 ; stdout
mov ecx, buf ; address of buffer
mov [ecx], al ; move al into buffer
mov edx, 1 ; just one char
mov eax, 4 ; __NR_write
int 0x80
cmp eax, byte 1
jne putc_error ; if anything but 1, something's wrong
popad ; restore caller's regs
ret ; return to caller
putc_error: ; again, unlikely
or ebx, byte -1
mov eax, 1 ; __NR_exit
int 0x80
;--------------------
section .bss
buf resb 4
;--------------------
okay i think i can generally understand the other portions. in c stdin, stdout and stderr are preopened when app starts. is this the same even when only using kernel? when writing readc i had thought that i should do a open with 0 before reading but i tried it without and it works, so i guess stdin, stdout and stderr are opened already by kernel when app starts?
i like this method better than push ... needed with c library. no need to pop anything also. also the reverse order in c is confusing :)
in nasm html manual the x86 instruction refarence is not linked in contents page. i had to load nasmdocb.html directly.
.
- Follow-Ups:
- Re: which book to start with...?
- From: Frank Kotler
- Re: which book to start with...?
- References:
- which book to start with...?
- From: naunetr
- Re: which book to start with...?
- From: Herbert Kleebauer
- Re: which book to start with...?
- From: naunetr
- Re: which book to start with...?
- From: Frank Kotler
- which book to start with...?
- Prev by Date: Re: which book to start with...?
- Next by Date: Re: simple read char app return wrong value?
- Previous by thread: Re: which book to start with...?
- Next by thread: Re: which book to start with...?
- Index(es):
Relevant Pages
|