Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Assembly x86 > Re: global star...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 7 of 8 Topic 4574 of 4710
Post > Topic >>

Re: global start, global main or anything I want?

by Frank Kotler <spamtrap@[EMAIL PROTECTED] > Mar 17, 2008 at 09:27 PM

phoenix wrote:
> Thank you guys for your responses. They' ve been very useful.
> 
> I' ve made some tests today, the result is that if I leave "prog" as
> the label name and then I use the GCC "-nostdlib " parameter, a
> warning message stating that there's no _stat function appears but the
> program (or function) is correctly linked. Using "-nostdlib "
> parameter, the executable file is just 744 byte, without "-nostdlib "
> parameter the executable file is about 7 kB!
> 
> My last question

Bet it isn't! :)

> is: what is the best way to write simple (addition,
> subtraction,...) STAND-ALONE assembly programs, without C libraries or
> external stuff (just pure assembly)? What about writing the code of
> the program with a _start label in it, then assembling and linking it,
> using the "-nostdlib " parameter (or using directly ld)? Or is there a
> better (or easier) way?

I think using ld directly is the easiest way. We can also use Nasm's "-f 
bin" mode, and "stuff" an elf executable header on the front...

> P.S.: why the executable stops with a segmentation fault? Am I forced
> to use the syscall exit?

Yes! If you're "call"ed, say "main" being called from the "startup" 
code, you can end with "ret". But the "_start" label is not called, it's 
"jmp"ed to. There is no return address on the stack, the first thing on 
the stack is the argument count, "argc". So a "ret" will attempt to 
return to "argc" as an address - probably 1 (our program name is 
"argv[0]", so "argc" is at least 1). This is outside "our" address 
space, and segfaults.

Addition and subtraction are simple enough, displaying the result is 
somewhat less obvious. If we send a number to stdout, it's treated as an 
ascii code, and the ascii codes for the "number characters" are not the 
same as the number! Fortunately, the decimal digit characters are 
contiguous, so we can add '0' (the character '0', *not* the number 0 - 
aka 48 decimal or 30h) to "convert" a number to its ascii code. That's 
good for *one* digit, if we've got more, we need to extract 'em one at a 
time. "div" will do this... there are faster ways. "div" puts the 
quotient in eax, and the remainder in edx... if we "div" by ten 
repeatedly, we get the digits we want, but "backwards" from the way we 
want to print 'em. Simplest way to "demo" this is to use a "static" 
buffer. This may be a little harder to follow, since it makes a 
"tem****ary" buffer on the stack. If ya *can't* follow it, we can start 
with something simpler... but you could "just use it"... ya don't know 
how "printf" works either, most likely...

Best,
Frank


; nasm -f elf hwint.asm
; ld -o hwint hwint.o

global _start

section .data

     hiya db "Hello, World of (real) Assembly Language!", 10
; "$", in this context, means "here", the current offset
; in the file, so this calculation counts characters.
     hiya_len equ $ - hiya

     ans db "InitDemo's value is "
     ans_len equ $ - ans

     InitDemo dd 5

section .text
_start:
     mov ecx, hiya
     mov edx, hiya_len
     call write_stdout

     mov ecx, ans
     mov edx, ans_len
     call write_stdout

     mov eax, [InitDemo]
     call showeaxd

     call newline

     xor eax, eax		; claim "no error".
exit:
     mov ebx, eax		; error/return code in ebx (bl, actually)
     mov eax, 1			; __NR_exit
     int 80h
;-----------------------

;---------------------------------
showeaxd:
     pusha			; save caller's regs

     sub esp, byte 10h		; make buffer on stack
     lea ecx, [esp + 10h]	; start at "end" of buffer
     mov ebx, 10			; for decimal, divide by 10
     xor esi, esi		; length counter
..top:
     dec ecx			; work towards "front" of buffer
     xor edx, edx		; "div" works with edx:eax!
     div ebx			; quotient in eax, remainder in edx
     add dl, '0'			; convert number to ascii char
     mov [ecx], dl		; store it
     inc esi			; count it
     or eax, eax			; quotient zero?
     jnz .top			; do more

     mov edx, esi		; length in edx
     call write_stdout		; print it

     add esp, byte 10h		; free the buffer

     popa			; restore caller's regs
     ret
;---------------------------------

;-------------------
newline:
     pusha
     push byte 10			; linefeed
     mov ecx, esp		; stack is the buffer
     mov edx, 1			; just one
     call write_stdout
     add esp, byte 4			; free buffer
     popa
     ret
;------------------

;------------------
write_stdout:
; expects buffer in ecx, length in edx
; trashes ebx!

     mov ebx, 1			; STDOUT
     mov eax, 4			; __NR_write
     int 80h
     ret
;-------------------
 




 8 Posts in Topic:
global start, global main or anything I want?
phoenix <spamtrap@[EM  2008-03-16 10:51:20 
Re: global start, global main or anything I want?
Tim Roberts <spamtrap  2008-03-16 21:25:30 
Re: global start, global main or anything I want?
Terence <spamtrap@[EM  2008-03-16 14:19:02 
Re: global start, global main or anything I want?
Frank Kotler <spamtra  2008-03-16 21:58:37 
Re: global start, global main or anything I want?
Robert Redelmeier <red  2008-03-16 22:32:37 
Re: global start, global main or anything I want?
phoenix <spamtrap@[EM  2008-03-17 03:25:33 
Re: global start, global main or anything I want?
Frank Kotler <spamtra  2008-03-17 21:27:21 
Re: global start, global main or anything I want?
phoenix <spamtrap@[EM  2008-03-19 01:01:59 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Sun Jul 6 20:12:08 CDT 2008.