📄 asm.inc
字号:
;=============================================================================
; Insight, real-mode debugger for MS DOS / PC DOS / FreeDOS.
; Copyright (c) Victor M. Gamayunov, Sergey Pimenov, 1993, 96, 97, 2002.
; Modifications by Oleg O. Chukaev (2006, 2007).
;-----------------------------------------------------------------------------
; asm.inc
; Assembler.
;-----------------------------------------------------------------------------
; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version 2
; of the License, or (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
; 02111-1307, USA.
;=============================================================================
;=============================================================================
; assemble
;-----------------------------------------------------------------------------
;ds:si -> assembling line
;es:di -> result buffer
;bx = jump/call offset origin
assemble:
cld
mov [asm_seg],es
mov [asm_offs],di
mov [jump_origin_offs],bx
mov [asm_sp],sp
push cs
pop es
mov byte [rep_pref],0
@@find_next:
call find_name
cmp bx,rep_prefixes
jb not_rep
mov al,[bx+5]
mov [rep_pref],al
jmp @@find_next
not_rep:
call upline
cmp byte [rep_pref],0
je @@no_rep
cmp byte [bx+6],-1
je @@no_rep
jmp rep_error
@@no_rep:
mov byte [jump_flag],0
cmp bx,jumps_and_calls
jb not_jumps
mov byte [jump_flag],1
not_jumps:
mov byte [param_count],0
mov byte [curr_prefix],-1
mov di,parameter_1
call get_parameter
jc ..@no_params
inc byte [param_count]
mov di,parameter_2
call get_parameter
jc one_param
inc byte [param_count]
mov al,[parameter_1+AP_WORD_FLAG]
mov ah,[parameter_2+AP_WORD_FLAG]
; or ax,ax
; jz TypeWarning
cmp bx,diff_types
jae @@1
cmp al,0
je @@1
cmp ah,0
je @@1
cmp al,ah
jne reg_error
@@1:
call skip_spaces
jz one_param
jmp extra_error
one_param:
; cmp Parameter1.WordFlag,0
; jz TypeWarning
..@no_params:
mov di,asm_buffer
mov cl,[bx]
lea si,[bx+3]
mov ch,0
next_proc:
push cx
mov bl,[parameter_1+AP_MEM_FLAG]
mov bh,[parameter_2+AP_MEM_FLAG]
mov cl,[parameter_1+AP_REG_NUMBER]
mov ch,[parameter_2+AP_REG_NUMBER]
lodsw
xchg ax,dx
lodsw
call dx
pop cx
loopne next_proc
jne wrong_param
mov es,[asm_seg]
mov di,[asm_offs]
mov si,asm_buffer
lodsb
mov cl,al
mov ch,0
cmp byte [rep_pref],0
jz @@ch_pr
mov al,[rep_pref]
stosb
@@ch_pr:
cmp byte [curr_prefix],-1
je @@copy
; cmp Parameter1.MemFlag,0
; jne @@Mem1
; cmp Parameter2.MemFlag,0
; je @@Copy
;@@Mem1:
mov al,[curr_prefix]
mov bx,pref_codes
xlat
stosb
@@copy:
rep movsb
clc
ret
rep_error:
mov ax,ER_REP_ERROR
jmp asm_error
;TypeWarning:
; mov ax,erParamType
; jmp AsmError
reg_error:
mov ax,ER_REG_BITS
jmp asm_error
wrong_param:
mov ax,ER_INV_PARAM
jmp asm_error
mnem_error:
mov ax,ER_MNEMONIC
asm_error: ; SI=error place
mov sp,[asm_sp] ; AX=error code
stc
ret
;=============================================================================
asm_seg dw 0
asm_offs dw 0
asm_sp dw 0
jump_origin_offs dw 0
;=============================================================================
; find_name
;-----------------------------------------------------------------------------
find_name:
call skip_spaces
jz no_name
mov di,name_buf
mov cx,MAX_LETTER
@@next_letter:
lodsb
call test_space
jz end_name
call lowcase
stosb
loop @@next_letter
jmp mnem_error
end_name:
dec si
mov al,0
stosb
push si
mov cx,di
mov bx,asm_table
mov si,name_buf
sub cx,si
next_mnem:
mov di,[bx+1]
push cx
push si
repe cmpsb
pop si
pop cx
je @@found
mov al,[bx]
cbw
shl ax,1
shl ax,1
add bx,ax
add bx,3
or ax,ax
jne next_mnem
jmp mnem_error
@@found:
; mov CurCmd,bx
pop si
ret
no_name:
mov ax,ER_EMPTY
jmp asm_error
;=============================================================================
; get_parameter
;-----------------------------------------------------------------------------
get_parameter:
call skip_spaces
jnz @@1
stc
jmp get_parameter_quit
@@1:
xor ax,ax
mov [di+AP_MEM_FLAG],al
mov [di+AP_WORD_FLAG],al
mov [di+AP_VALUE],ax
mov byte [di+AP_REG_NUMBER],-1
mov [minus_flag],al
..@next:
mov ax,[si]
call get_xptr
jz ..@next
cmp al,'$'
je @@j$
cmp al,'['
jne @@skip
jmp ..@mem_start ;jump out of range
@@skip:
call find_seg_reg
jz seg_reg_param
call find_reg
je reg_param ;jump out of range
cmp al,'-'
jne @@nm
mov byte [minus_flag],1
inc si
@@next_val:
mov ax,[si]
@@nm:
call test_hex
jc jump_to_wrong_param_1 ;jump out of range
call get_value
@@add_offs:
cmp byte [minus_flag],0
je @@pl
neg dx
mov byte [minus_flag],0
@@pl:
add [di+AP_VALUE],dx
lodsb
cmp al,'+'
je @@next_val
cmp al,'-'
jne ..@emp
mov byte [minus_flag],1
jmp @@next_val
@@j$:
; mov dx,asm_offs
mov dx,[jump_origin_offs]
inc si
jmp @@add_offs
seg_reg_param:
cmp byte [si+2],':'
je ..@prefix
mov dx,[bx+1]
cmp dx,cmov
je ..@okp
cmp dx,cpush
je ..@okp
cmp dx,cpop
je ..@okp
jump_to_wrong_param_1:
jmp wrong_param
reg_param:
mov [di+AP_REG_NUMBER],al
mov dl,1
test al,1000b
jz byte_reg
inc dl
byte_reg:
mov [di+AP_WORD_FLAG],dl
..@check_extra:
inc si
inc si
jmp check_extra
..@emp:
dec si
cmp byte [jump_flag],0
je check_extra
lodsb
cmp al,':'
je far_jump
dec si
check_extra:
call skip_spaces
jz @@jump_to_ok_quit ;jump out of range
cmp al,','
jnz extra_error ;jump out of range
inc si
@@jump_to_ok_quit:
jmp ..@ok_quit
extra_error:
mov ax,ER_EXTRA
jmp asm_error
far_jump:
mov al,[si]
call test_hex
jc check_extra
call get_value
mov [far_value],dx
mov byte [jump_flag],2
jmp check_extra
..@okp:
add al,10h
mov [di+AP_REG_NUMBER],al
mov byte [di+AP_WORD_FLAG],2
jmp ..@check_extra
..@prefix:
cmp byte [curr_prefix],-1
jne jump_to_wrong_param_1 ;jump out of range
mov [curr_prefix],al
add si,3
call skip_spaces
jmp ..@next
..@mem_start:
mov byte [di+AP_MEM_FLAG],1
xor ax,ax
mov [di+AP_BX_FLAG],ax ;Also clear [di+AP_BP_FLAG]
mov [di+AP_SI_FLAG],ax ;Also clear [di+AP_DI_FLAG]
inc si
..@plus:
next_mem_param:
call skip_spaces
jz jump_to_bad_mem_param ;jump out of range
mov ax,[si]
cmp al,'$'
je @@$
call find_reg
je mem_reg
..@get_value:
call test_hex
jc jump_to_bad_mem_param ;jump out of range
call get_value
cmp byte [minus_flag],0
je @@2
neg dx
mov byte [minus_flag],0
@@2:
add [di+AP_VALUE],dx
jmp ..@3
@@$:
; mov dx,asm_offs
mov dx,[jump_origin_offs]
inc si
jmp @@2
mem_next:
inc si
inc si
..@3:
call skip_spaces
jz jump_to_bad_mem_param
lodsb
cmp al,']'
je mem_end
cmp al,'+'
je ..@plus
cmp al,'-'
je ..@minus
jump_to_bad_mem_param:
jmp bad_mem_param
..@minus:
mov byte [minus_flag],1
call skip_spaces
jnz ..@get_value
jmp bad_mem_param
mem_reg:
cmp al,regBX
jne @@bp
cmp word [di+AP_BX_FLAG],0
jne bad_mem_param
inc byte [di+AP_BX_FLAG]
jmp mem_next
@@bp:
cmp al,regBP
jne @@si
cmp word [di+AP_BX_FLAG],0
jne bad_mem_param
inc byte [di+AP_BP_FLAG]
jmp mem_next
@@si:
cmp al,regSI
jne @@di
cmp word [di+AP_SI_FLAG],0
jne bad_mem_param
inc byte [di+AP_SI_FLAG]
jmp mem_next
@@di:
cmp al,regDI
jne bad_mem_param
cmp word [di+AP_SI_FLAG],0
jne bad_mem_param
inc byte [di+AP_DI_FLAG]
jmp mem_next
mem_end:
jmp check_extra
..@ok_quit:
clc
get_parameter_quit:
ret
bad_mem_param:
mov ax,ER_MEM_PARAM
jmp asm_error
;=============================================================================
; get_xptr
;-----------------------------------------------------------------------------
get_xptr:
cmp byte [di+AP_WORD_FLAG],0
jne @@4
cmp al,'W'
je ..@check_word
cmp byte [jump_flag],1
je jump_xptr
cmp al,'B'
je ..@check_byte
@@4:
ret
jump_xptr:
cmp ax,'FA'
je @@check_far
cmp ax,'DW'
je @@check_dw
cmp ax,'SH'
je @@check_short
ret
@@check_short:
lodsw
lodsw
cmp ax,'OR'
je @@cs_1
ret
@@cs_1:
lodsb
cmp al,'T'
je @@check_ptr
ret
@@check_far:
lodsw
lodsb
mov dl,3
cmp al,'R'
je @@check_ptr
ret
@@check_dw:
lodsw
lodsw
mov dl,3
cmp ax,'OR'
je @@cd_2
ret
@@cd_2:
lodsb
cmp al,'D'
je @@check_ptr
..@check_byte:
mov dl,1
cmp ah,'/'
je @@ptr_1
cmp ah,'Y'
je @@check_byte_1
ret
..@check_word:
mov dl,2
cmp ah,'/'
je @@ptr_1
cmp ah,'O'
je @@check_word_1
ret
@@ptr_1:
mov [di+AP_WORD_FLAG],dl
inc si
inc si
..@get_xptr_quit:
call skip_spaces
jz jump_to_wrong_param_2
cmp ax,ax
ret
@@check_byte_1:
lodsw
lodsw
cmp ax,'TE'
je @@check_ptr
ret
@@check_word_1:
lodsw
lodsw
cmp ax,'RD'
je @@check_ptr
ret
@@check_ptr:
call skip_spaces
jnz ..@not_spc
jump_to_wrong_param_2:
jmp wrong_param
..@not_spc:
cmp al,'['
je @@ok
cmp al,'$'
je @@ok
call test_hex
jnc @@ok
lodsw
cmp ax,'PT'
jne @@quit_2
lodsb
cmp al,'R'
je @@ok
@@quit_2:
ret
@@ok:
mov [di+AP_WORD_FLAG],dl
jmp ..@get_xptr_quit
;=============================================================================
; find_seg_reg
;-----------------------------------------------------------------------------
find_seg_reg:
push di
mov di,asm_seg_regs
mov cx,4
repne scasw
jne @@quit
lea ax,[di-(asm_seg_regs-offset_0100h+102h)]
shr ax,1
cmp ax,ax
@@quit:
pop di
ret
;=============================================================================
asm_seg_regs db 'ESCSSSDS'
;=============================================================================
; find_reg
;-----------------------------------------------------------------------------
find_reg:
push di
mov di,asm_regs
mov cx,16
repne scasw
jne @@quit
lea ax,[di-(asm_regs-offset_0100h+102h)]
shr ax,1
cmp ax,ax
@@quit:
pop di
ret
;=============================================================================
asm_regs db 'ALCLDLBLAHCHDHBH'
db 'AXCXDXBXSPBPSIDI'
;=============================================================================
; test_hex
;-----------------------------------------------------------------------------
test_hex:
cmp al,'0'
jb @@not
cmp al,'9'
jbe @@hex
cmp al,'A'
jb @@not
cmp al,'F'
ja @@not
@@hex:
clc
ret
@@not:
stc
ret
;=============================================================================
; get_value
;-----------------------------------------------------------------------------
get_value:
xor dx,dx
@@next:
lodsb
sub al,'0'
jb @@end
cmp al,9
jbe @@digit
cmp al,'A'-'0'
jb @@end
cmp al,'F'-'0'
ja @@end
sub al,7
@@digit:
test dh,0f0h
jnz big_num_error
shl dx,1
shl dx,1
shl dx,1
shl dx,1
or dl,al
jmp @@next
@@end:
dec si
ret
big_num_error:
mov ax,ER_BIG_NUMBER
jmp asm_error
;=============================================================================
; skip_spaces
;-----------------------------------------------------------------------------
skip_spaces:
@@next:
lodsb
cmp al,' '
je @@next
cmp al,9
je @@next
dec si
cmp al,0
je @@ok
cmp al,';'
@@ok:
ret
;=============================================================================
; test_space
;-----------------------------------------------------------------------------
test_space:
cmp al,' '
je @@ok
cmp al,9
je @@ok
cmp al,0
je @@ok
cmp al,';'
@@ok:
ret
;=============================================================================
;~ifndef __ACT__
;~;------------------------------------------------------------------------------
;~UpCase: ;~proc
;~ cmp al,'a'
;~ jb @@1
;~ cmp al,'z'
;~ ja @@1
;~ sub al,20h
;~@@1:
;~ ret
;~ ;~endp
;~endif
;=============================================================================
asm_table:
db 3
dw cadd
dw _r_rm
db 0, 0
dw _a_im
db 4, 0
dw _rm_im
db 80h, 0
db 3
dw cor
dw _r_rm
db 8, 0
dw _a_im
db 0Ch, 0
dw _rm_im
db 80h, 1
db 3
dw cadc
dw _r_rm
db 10h, 0
dw _a_im
db 14h, 0
dw _rm_im
db 80h, 2
db 3
dw csbb
dw _r_rm
db 18h, 0
dw _a_im
db 1Ch, 0
dw _rm_im
db 80h, 3
db 3
dw cand
dw _r_rm
db 20h, 0
dw _a_im
db 24h, 0
dw _rm_im
db 80h, 4
db 3
dw csub
dw _r_rm
db 28h, 0
dw _a_im
db 2Ch, 0
dw _rm_im
db 80h, 5
db 3
dw cxor
dw _r_rm
db 30h, 0
dw _a_im
db 34h, 0
dw _rm_im
db 80h, 6
db 3
dw ccmp
dw _r_rm
db 38h, 0
dw _a_im
db 3Ch, 0
dw _rm_im
db 80h, 7
db 3
dw ctest
dw _r_rm
db 84h, 0
dw _a_im
db 0A8h, 0
dw _rm_im
db 0F6h, 0
db 5
dw cmov
dw _sr_rm
db 8Ch, 0
dw _r_im
db 0B0h, 0
dw _a_mem
db 0A0h, 0
dw _r_rm
db 88h, 0
dw _rm_im1
db 0C6h, 0
db 3
dw cpush
dw _sreg
db 6, 0
dw _reg16
db 50h,0
dw _rm
db 0FFh, 6
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -