SDCCをZ80で使用する場合、Cのmainプログラムが開始する前及び、終了した後の
動作をプログラムしておく必要があります。通常はOSが何気なくやっていますが、組み
込み用ではお膳立てが必要になってきます。

このお膳立てプログラムが、 crt0.s(ソースの場合)ですが中身をみるといろいろ
やってる(スタックポインターの初期化など)ので、自分用の作るのがいいかもしれません。
通常のコンパイルでは、このcrt0.sが自動的にリンクされます。
ちなみに、デフォルトのcrt0.sは下記のところに置いてあります。

$ cd /usr/local/share/sdcc/lib/src/z80/
$ ls
README crt0.s divunsigned.s modsigned.s putchar.s
__sdcc_call_hl.s crtenter.s heap.s modunsigned.s setjmp.s
__sdcc_call_iy.s divmixed.s memmove.s mul.s strcpy.s
abs.s divsigned.s modmixed.s mulchar.s strlen.s

自分用のcrt0.sをmycrt.asmとして作成します。
作成条件として下記のとおりです。

1、開始アドレス 0x0000よりスタートし、0x0100へジャンプ(コンパイル時指定)
2、初期設定プログラムとして 0x0100から配置(コンパイル時指定)
3、スタックポインター 0x8000 に設定 (0x4000~0x7FFFまでがRAMとして仮定)
4、main()から戻ってきたら即、halt実行(Z80停止)

mycrt.asmは次のようになります。

.module mycrt
.globl _main

.area  _HEADER (ABS)
.org 0
jp init

.area  _CODE
init:
ld sp,#0x8000
call _main
halt

このmycrt.asmをアセンブルして、リンク用オブジェクトを作成します。

$ sdasz80 -o mycrt.o mycrt.asm

確認用のCプログラムを作成します。
単に戻り値を返すだけのmain()を作成します。

int main(void)
{
    return 0;
}

test.cとして保存して、コンパイルします。

$ sdcc test.c -mz80 --code-loc 0x0100 --no-std-crt0 -Wlmycrt.o

コンパイルオプション --code-loc 0x0100 で コード領域を 0x0100から配置
コンパイルオプション --no-std-crt0 で デフォルトのcrt0.oをリンクしない
コンパイルオプション  -Wlmycrt.o で 自分用のmycrt.oをリンク

アセンブルリストを確認
$ more test.asm

--------------------------------------------------------
; File Created by SDCC : free open source ANSI-C Compiler
; Version 3.5.0 #9253 (Dec 10 2015) (Linux)
; This file was generated Sun Dec 13 09:17:21 2015
;--------------------------------------------------------
.module test
.optsdcc -mz80

;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
.globl _main
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
.area _DATA
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
.area _INITIALIZED
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
.area _DABS (ABS)
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
.area _HOME
.area _GSINIT
.area _GSFINAL
.area _GSINIT
;--------------------------------------------------------
; Home
;--------------------------------------------------------
.area _HOME
.area _HOME
;--------------------------------------------------------
; code
;--------------------------------------------------------
.area _CODE
;test.c:1: int main(void)
; ---------------------------------
; Function main
; ---------------------------------
_main::
;test.c:3: return 0;
ld hl,#0x0000
ret
.area _CODE
.area _INITIALIZER
.area _CABS (ABS)

コンパイルされたhexコードで確認してみます。
$ more test.ihx

:03000000C3000139
:0B010000310080CD070176210000C90E
:00000001FF

ちょっとわかりずらいのでコードを抜き出してみると
0000:   C30001   ;JP 0x0100

0100:   310080   ;LD  SP,0x8000
0103:        CD0701      ;CALL  0x0107
0106:        76               ;HALT

0107:       210000       ;LD HL,0x0000
010A:      C9               ;RET

とりあえず意図したコードになっていましたwww 
main()のreturnの戻り値は HLレジスターに設定されるようです。

参考ブログ
Tosikの雑記 様  SDCCでクロス開発環境をインストールと使い方(Z80用) 

おすすめの記事