⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e3.asm

📁 e3 是一个全屏的用户友好的文本编辑器
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;--------------------------------------------------------------------;;  e3.asm v2.41 Copyright (C) 2000-2003 Albrecht Kleine <kleine@ak.sax.de>;;  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., 675 Mass Ave, Cambridge, MA 02139, USA.;;----------------------------------------------------------------------;%include "e3.h";section .textbits 32	ORGheaderglobal _start;; start with OUTER editor loop;_start:	call SetTermStruc%ifdef SELFTEST	mov eax,mode	mov byte [eax],WS		;store current editor mode:  WS only..	mov esi,pipein			;...because the test file expects WS "syntax"%else%ifdef W32	push byte 0	push dword 8192			;initial size (to be extended)	push byte 0	call HeapCreate	mov [heap],eax;------	mov eax,mode	mov byte [eax],DEFAULT_MODE	;store default editor mode	call GetCommandLineA		;eax points to  either	D:\PATH\E3.EXE args1 args2 args3...	xchg eax,esi			;               or	"d:\path\e3.exe"	;-- for debug only --		;		or	e3.exe "args"	;pusha	;push dword 0			;single OK button	;push dword esi	;push dword esi	;push dword 0	;call MessageBoxA		;show cmd line	;popa	;--------------------	cld	xor ebx,ebx	cmp byte [esi],'"'		;due above mentined 2 different cmd line ways	jnz prog	dec ebx				;ebx -1 due pending '"'prog:	lodsb	or al,al	jz prog9	cmp al,SPACECHAR		;TODO chk TABs	ja prog	inc esiprog9:	dec esiprog0:	push esi	lea esi,[esi+ebx-4-5]		;-4 due suffix ".exe"	call SetEditMode	jz prog1	mov byte [eax],DEFAULT_MODE	;store current editor modeprog1:	pop esi	xor edx,edx			;no argsprog2:	lodsb	or al,al	jz prog3	cmp al,SPACECHAR	jbe prog2	dec esi	jmp short prog5prog3:	mov esi,edxprog5:%else%ifdef BEOS ;-----------------------------------------------------------	pop eax	pop ebx				;args counter (1....x)	pop esi	mov esi,[esi]			;points to our_name0[args]0env.....	cldprog:	lodsb	or al,al	jne prog	mov edx,esi			;store arg ptr	lea esi,[esi-5]	call SetEditMode	jz prog1	mov byte [eax],DEFAULT_MODE	;store current editor modeprog1:	xor esi,esi			;init for 'no args'	dec ebx	jz noarg	mov esi,edxnoarg:%else%ifdef DYN ;------------------------------------------------------------; This is to be called from dynamic linked libc startup code ; just like you would expect:  int main(int argc,char**argv); (for experimental purpose only);	xor esi,esi			;init to "no args"	mov ecx,[esp+4]			;"int argc"	cmp ecx,1	je NoArg	mov esi,[esp+8]			;"char**argv"	mov esi,[esi]	cldArgl:	lodsb	or al,al	jne ArglNoArg:	mov eax,mode	mov byte [eax],DEFAULT_MODE	;store current editor mode (WS only)%undef CURSORMGNT%else	;-------------- i.e. Linux, FreeBSD, QNX, Ath ------------------%ifdef SYS_sigaction	call SetSigHandler%endif;-------%ifdef ATHEOS	pop edx	pop edx	pop edx%endif	pop edx				;Linux: arguments #	pop esi				;Linux: argv[0]	cldprog:	lodsb	or al,al	jne prog			;get program name	lea esi,[esi-5]	call SetEditMode	jz prog1	mov byte [eax],DEFAULT_MODE	;store current editor modeprog1:;-------	pop esi				;Linux: esi points to first arg (filename)%endif%endif%endif%endif;-------%ifdef CURSORMGNT	or esi,esi	jz moreenvmorearg:pop ecx				;arguments until NULL	or ecx,ecx        jnz morearg;-------moreenv:pop ecx	jecxz ReStart%ifndef ARMCPU	cmp dword[ecx],'TERM'		;a short test for "TERM=linux"	jnz moreenv	cmp dword[ecx+5],'linu'%else	cmp byte[ecx],'T'	jnz moreenv	cmp byte[ecx+1],'E'	jnz moreenv	cmp byte[ecx+2],'R'	jnz moreenv	cmp byte[ecx+3],'M'	jnz moreenv	cmp byte[ecx+5],'l'	jnz ReStart	cmp byte[ecx+6],'i'	jnz ReStart	cmp byte[ecx+7],'n'	jnz ReStart	cmp byte[ecx+8],'u'%endif	jnz ReStart	add byte[revvoff],boldlen	;special inverse cursor on linux terminals%endif;-------ReStart:call NewFile	jc E3exitMainCharLoop:call ChkCursPos	call IsViMode	jnz MCL	mov ecx,[blockbegin]	jecxz MCL	push edi	mov edi,ecx			;for vi only: keep Begin/End-line marker together	call KeyEnd	; <------prev line------------>	; BegM......marker line........EndM	; <-------next line----------->	mov [blockende],edi		;set WS's "blockende" to one after EOL for VI marker	pop edi	call ShowBl1			;i.e. "mov byte [showblock],1";-------MCL:	call DispNewScreen	call RestoreStatusLine	call HandleChar%ifdef W32LF	cmp byte [edi],RETURN		;never stay at character 0dh	jnz MCL2	inc edi				;(rather stay at following 0ah)MCL2:%endif	mov ebx,endeedit	cmp byte [ebx],0	je MainCharLoop	xor esi,esi			;just like if no arg is present	cmp byte [ebx],2	je ReStart			;^KD repeat edit using another fileE3exit:	call KursorStatusLine%ifdef W32	push dword w32result		;reset all to standard colors	push byte 0	mov eax,[lines]	inc eax	mov ebx,[columns]	mul bl	push eax	push byte DARKWHITE		;equ 7	push dword [hout]	call FillConsoleOutputAttribute%endif	mov ecx,text			;enter next line on terminal NEWLINE is @ byte [text]	call WriteFile00;-------	mov ebx,tempfile2		;undo info (if exist)	call Unlink%ifdef W32	push dword [heap]	call HeapDestroy	push byte 0			;return code	call ExitProcess		;Ready&Exit%else	mov ecx,TERMIOS_SET 	call IOctlTerminal0		;restore termios settings	jmp Exit%endif;----------------------------------------------------------------------;; MAIN function for processing keys;HandleChar:call ReadChar	cmp ah,0xFF			;normal chars get 0xFF in ah	jne near ExtAscii		;go handling Cursor-Keys	mov esi,mode	test byte [esi], EM | PI	jz NO_EM01	cmp al,11	je IsCtrlK	mov byte [EmaCtrlK],0IsCtrlK:cmp al,13h			;^S	je IsCtrlS	cmp al,12h			;^R	je IsCtrlS	mov byte [EmaCtrlS],0IsCtrlS:NO_EM01:cmp byte [esi],VI	jz ISVI1	cmp al,32			;in WS,EM,PI,NE: handle control chars	jae NormChar	mov bl,al	add bl,jumps1	cmp byte [esi],WS	je CJump	add bl,32	cmp byte [esi],EM	je CJump	add bl,32	cmp byte [esi],PI	je CJump	add bl,32CJump:	jmp CompJump2ISVI1:					;in VI: most control is done in command mode...	cmp al,7			;... so maintaining another table for <Return>...	je near KeyDel			;... <Del> and <DelLeft> is useless	cmp al,8	je near KeyDell	cmp al,RETURN	je near KeyRet;-------NormChar:test byte [mode], EM | PI	jz NOEM0	call ShowBl0			;i.e. "mov byte [showblock],0"NOEM0:	call CheckMode%ifdef USE_UNDO	jz NormCh2	call DataForUndoOverwrite	jmp short OverWriteChar%else	jnz OverWriteChar%endif	NormCh2:push eax%ifdef W32LF	call CheckEof	jz noEOL	cmp word [edi-1],RETURN|(NEWLINE<<8)	jnz noEOL	dec edi				;move back to 0DhnoEOL:%endif	call Insert1Byte	pop eax	jc InsWriteEnd			;error: text buffer fullOverWriteChar:cld	stosbSetChg:	mov byte [changed],CHANGEDInsWriteEnd:ret;-------KeyVICmdr:call ReadOneChar		;repl one char (except newline)	cmp byte [edi],NEWLINE	je InsWriteEnd	cmp al,RETURN	jnz KeyVICmdr1	mov al,NEWLINEKeyVICmdr1:%ifdef USE_UNDO	call DataForUndoOverwrite%endif	KeyVICmdr2:mov byte [edi],al	jmp short SetChg;-------KeyEmaCtrlQ:mov esi,asknumber	call GetOctalToInteger	jbe InsWriteEnd	xchg eax,ecx			;using decimal input for ASCII value	cmp eax,256	jb NormCh2	ret;-------;; helper for HandleChar;CtrlKMenu:mov ebx,Ktable	mov al,'K'	jmp short MenuCtrlQMenu:mov ebx,Qtable	jmp short PicoQMPicoJMenu:mov ebx,PicoJtable	mov al,'J'	jmp short MenuPicoQMenu:mov ebx,PicoQtablePicoQM:	mov al,'Q'	jmp short MenuCtrlXMenu:mov ebx,Xtable	mov al,'X'Menu:	mov ecx,2020205eh	mov ch,al;-------MakeScanCode:call WriteTwo		;ebx expects xlat-table	push ebx	call GetChar	pop ebx	and al,01fh	cmp al,Ktable_size	jnb InsWriteEnd			;if no valid scancode	xlatb	mov ah,al			;=pseudo "scancode";------- contExtAscii:mov bl,ah			;don't use al (carries char e.g. TAB)	cmp bl,jumps1	jae InsWriteEnd	xor eax,eax	mov [EmaCtrl],eaxCompJump2:mov bh,0	lea ebx,[bx]			;1 byte shorter than 'and ebx,0ffh'	movzx ebx,word [2*ebx+jumptab1] ;2*ebx is due 2 byte per entry	add ebx,_start			;offset inside code;-------	call ebx			;the general code jump dispatcher;-------	cmp byte [numeriere],1		;after return from functions...	jnz BZNret			;...decide whether count current line number	push edi	mov esi,sot	xchg esi,edi	xor edx,edxBZNLoop:inc edx				;edx=linenr counter	call LookForward	inc edi				;point to start of next line	cmp edi,esi	jbe BZNLoop	mov [linenr],edx	pop edi	mov byte [numeriere],0BZNret:	ret;----------------------------------------------------------------------;; processing special keys: cursor, ins, del;KeyRetNoInd:xor eax,eax	jmp short KeyRetNIndKeyRet:	;;; %define NO_AUTO_INDENT		;for Izzy%ifndef NO_AUTO_INDENT%ifdef SELFTEST	xor eax,eax%else	call CheckMode	jnz  OvrRet	call CountToLineBegin		;set esi / returns eax	inc esi	inc esi	or eax,eax	jz KeyRetNInd	mov ebx,eax		xor eax,eax	dec eaxKeyRetSrch:inc eax			;search non (SPACE or TABCHAR)	cmp eax,ebx	jae KeyRetNInd	cmp byte [esi+eax],SPACECHAR	je KeyRetSrch	cmp byte [esi+eax],TABCHAR	je KeyRetSrch%endif%else	xor eax,eax%endifKeyRetNInd:push esi	push eax			;eax is 0 or =indented chars	call GoDown	pop eax	push eax%ifdef W32LF	inc eax				;1 extra for RETURN	call CheckEof	jz noEOL2	cmp word [edi-1],RETURN|(NEWLINE<<8)	jnz noEOL2	dec edi				;move back to 0DhnoEOL2:%endif	call InsertByte0		;1 extra for NEWLINE	pop ecx				;# blanks	pop esi				;where to copy	jc SimpleRet	inc dword [linenr]	cld%ifdef W32LF	mov ax,RETURN|(NEWLINE<<8)	;insert 0d0ah combination	stosw%else	mov al,NEWLINE	stosb%endif	jecxz SimpleRet	rep movsb			;copy upper line i.e. SPACES,TABS into nextSimpleRet:retOvrRet:	xor eax,eax	mov [ch2linebeg],eax	jmp short DownRet;-------KeyDown:call CountColToLineBeginVisDownRet:call GoDown	call LookLineDown	jmp short JmpSC;-------KeyUp:	call GoUp	call CountColToLineBeginVis	call LookLineUp	jmp short JmpSC;-------KeyHalfPgUp:call CountColToLineBeginVis	call LookHalfPgUp	jmp short SetColumn;-------KeyHalfPgDn:call CountColToLineBeginVis	call LookHalfPgDn	jmp short SetColumn;-------KeyScrollUp:call CountColToLineBeginVis	call LookScrUp	jmp short SetColumnKeyScrollDn:call CountColToLineBeginVis	call LookScrDn	jmp short SetColumn;-------KeyPgUp:call CountColToLineBeginVis	call LookPageUpJmpSC:	jmp short SetColumn;-------KeyPgDn:call CountColToLineBeginVis	call LookPgDown			;1st char last lineSetColumn:mov ecx,[ch2linebeg]		;=maximal columns	xor edx,edx			;counts visible columns i.e. expand TABs	dec ediSCloop:	inc edi	cmp edx,ecx			;from CountColToLineBeginVis	jae SCret	cmp byte [edi],NEWLINE		;don't go beyond line earlier line end	jz SCret	cmp byte [edi],TABCHAR	jz SCtab	inc edx				;count columns	jmp short SCloopSCtab:	call SpacesForTab	add dl,ah	cmp edx,ecx			;this tab to far away right?	jna SCloop			;noSCret:	ret;----------------------------------------------------------------------;; a helper for d'a and y'a vi commands; have to differ whether cursor is below or above the marked line; (at all this line based concept does not fit very well into e3); expects:;	ecx valid begin of marked line;	edi cursorVIsetMarker:cmp edi,ecx	ja Marker_above_cursor	; X........cursor line.......	; ...........................	; .........marker line.......	; Y	mov ecx,[blockende]	inc ecx	cmp ecx,ebp	jb Mbel	dec ecxMbel:	mov dword [EmaMark],ecx		;i.e. store point Y;------- contKeyHome:call CountToLineBegin		;i.e. goto point X	sub edi,eax	ret;-------Marker_above_cursor:	; Y.......marker line .......		; ...........................	; ........cursor line........	; X				;									mov dword [EmaMark],ecx		;i.e. store point Y	call KeyEnd	inc edi				;i.e. goto point X	cmp edi,ebp	jb Mret	dec ediMret:	ret;----------------------------------------------------------------------KeyIns:	not byte [insstat]	xor eax,eax	call IsViMode	jnz KeyIns2	inc eax	cmp byte [VICmdMode],al	jne KeyIns2	mov byte [insstat],al	call KeyVImode0KeyIns2:call IsEmMode	jnz KeyIns3	mov byte [showblock],alKeyIns3:ret;-------KeyVICmdJ:call KeyEnd	jmp short KeyDel;-------KeyDell:call KeyLeft	jz KeyDell2KeyDel:	cmp edi,ebp	jnb KeyIns3	xor eax,eax			;delete one @ cursor	inc eax%ifdef W32LF	cmp byte [edi-1],RETURN	jnz KD2	dec edi				;delete one more	inc eaxKD2:%endif;-------	call IsViMode	jne near DeleteByte	mov esi,edi			;make vi's x and X pasteable	mov byte [VInolinebased],1	call KeyEmaAltW2	jmp DeleteByte;-------	KeyDell2:cmp edi,sot			;delete newline char	jbe KeyIns3	dec dword [linenr]	dec edi	jmp KeyCtrlT1;-------KeyEmaCtrlT:cmp edi,sot			;xchg 2 chars	jbe KeyRightEnd	cmp byte [edi],NEWLINE	jnz KECT	dec ediKECT:	%ifdef USE_UNDO	call DataForUndoXchange%endif	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -