Важная информация

User Tag List

Показано с 1 по 10 из 23

Тема: try-catch на ассемблере z80

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1
    Master Аватар для siril
    Регистрация
    01.02.2005
    Адрес
    perm/ru
    Сообщений
    520
    Записей в дневнике
    1
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию try-catch на ассемблере z80

    Подумал я: а возникни у меня необходимость обрабатывать исключения и подниматься к процедуре catch с произвольной глубины подпрограммы, как бы я это реализовал на z80?


    Вот пример на sjasmplus:
    Код:
    ; macro
    	macro border color
    		ld a,color
    		out (#fe),a
    	endm
    	
    	macro set_page pagenum
    		ld a,pagenum
    		ld bc,#7ffd
    		out (c),a
    	endm
    	macro stop
    		jp $
    	endm
    	
    ;try-catch macro {
      	macro try catch_addr
    		ld hl, catch_addr
    		call begtry_subr
      		endm
      		
    	macro epop_2
    		ld hl,(esp)
    		inc hl,hl,hl,hl
    		ld (esp),hl
    	endm
    
    	macro raise exception
    		ld sp,(esp) ; restore alt stack
    		pop de      ; pop adress of main stack
    		pop hl      ; pop adress of "catch"
    		ld (esp),sp ; store alt stack
    		ex de,hl
    		ld sp,hl
    		ld a,exception
    		ex de,hl
    		jp (hl)
    	endm
    
    	macro epush_hl_sp
    		ld   (tsp),sp ; save main stack
    		ld   sp,(esp) ; restore alt stack
    		push hl       ; push catch_adress to alt stack
    		ld   hl,(tsp) ; 
    		push hl       ; push main stack top to alt stack
    		ld   (esp),sp ; save alt stack
    		ld   sp,(tsp) ; restore main stack
    	endm
    	
    	macro endtry
    		call endtry_subr
    	endm	
    ;} try-catch macro 
    	
    	
    	device ZXSPECTRUM128
    	
    	org #6000
    init		
    	di	
    ; устанавливаем обработчик исключений на процедуру по адресу catch0
    	try catch0
    	call setup
    	call start
    ; снимаем обработчик исключений по endtry
      	endtry
      	ld a,'A' ;ok
    	ret
    ; сюда попадём по raise с любой глубины 
    catch0
    	ld a,'B' ;plan 'B' =)
    	ret
    	
    ;
    	ifused begtry_subr
    begtry_subr
     	epush_hl_sp
    	ret
    	endif
    	ifused endtry_subr
    endtry_subr
     	epop_2
    	ret
    	endif
    
    ;----------------------------------------------------------------
    setup
    		call set_screen
    		ret
    start
    		ret
    		
    set_screen
    	di
    	call cls
    	call scr_grid
    	ei
    	ret
    
    cls
    	ld hl,#4000
    	ld de,#4001
    	ld bc,#17ff
    	ld a,#00
    	ld (hl),a 
    	ldir
    	ret
    scr_grid
    
    	ld hl,#5800
    	ld de,#5802
    	ld b,12
    scr_grid_lp1
    	push bc
    	ld bc,#20
    	ld a,#0f | #40
    	ld (hl),a 
    	inc hl
    	ld a,#0f | #00
    	ld (hl),a 	
    	dec hl
    	ldir
    	
    	ld bc,#20
    	ld a,#0f | #00
    	ld (hl),a 
    	inc hl
    	ld a,#0f | #40
    	ld (hl),a 	
    	dec hl		
    	ldir
    ; вызываем исключение:
            raise 1
    
    	pop bc
    	djnz scr_grid_lp1
    	ret
    
    program_end
    ;{DATA ---------------------------------------------------------------
    data_start
    
    ;alternative exceptions stack top:
    estack_top equ #bfff
    esp dw estack_top    ;alt stack pointer storage
    tsp dw #0000         ;main stack pointer temp storage
    
    
    data_end
    ;DATA }			
    		
    		savesna "try_catch_sample.sna",#6000
        display "program lenght", /a, program_end - init
        display "data lenght", /a, data_end - data_start
    Ну, то есть идея проста: по инструкции try запомнить текущий адрес основного стека на альтернативном стеке, там же на альтернативном стеке сохранить адрес процедуры catch.

    В случае если всё ок, и мы без приключений добрались до инструкции endtry - поднимаем указатель альтернативного стека на 4 (2 байта - адрес указателя основного стека и 2 байта - адрес процедуры catch).

    По инструкции raise - забираем с альтернативного стека указатель основного стека на момент инструкции try, а также адрес процедуры catch, на которую и совершаем безусловный переход, предварительно поместив в регистр A - код исключения.

    Соответственно инструкции try-catch могут быть вложенными - достаточно лишь предусмотреть необходимую глубину альтернативного стека. Адрес которого задаётся двухбайтовым словом по адресу esp. (В примере это estack_top equ #bfff).

    Есть ли более короткий/эффективный/разумный способ обработки исключений на асме z80? =)

    И насколько оправданно пользоваться описанным выше способом? =)
    oisee.

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Арифметические процедуры на ассемблере
    от spensor в разделе Программирование
    Ответов: 27
    Последнее: 13.05.2017, 20:56
  2. Пишем на ассемблере под эмулятором
    от GM BIT в разделе Для начинающих
    Ответов: 76
    Последнее: 15.07.2016, 20:04
  3. Ответов: 6
    Последнее: 07.02.2016, 11:55
  4. Ответов: 30
    Последнее: 14.01.2011, 15:13
  5. Подпрограмма на ассемблере в памяти?
    от jimled в разделе Программирование
    Ответов: 1
    Последнее: 29.11.2009, 06:46

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •