放牧代码和思想
专注自然语言处理、机器学习算法
    This thing called love. Know I would've. Thrown it all away. Wouldn't hesitate.

Win64下集成RadASM+nasm编写操作系统

这个标题有点唬人,我只是在看《自己动手写操作系统》的第二版《ORANGE’S:一个操作系统的实现》。作者喜欢命令行,我喜欢IDE。我尝试在RadASM下实现了第一个例子的编译与载入,觉得还不错。

RadASM默认只支持用Nasm开发win32应用程序,而写操作系统需要生成bin文件,只能自己修改配置来实现。本着瞎折腾的精神,我就折腾了一个nasm.ini,注意我将32位的nasm编译器放到了安装目录下的Nasm32目录中,所以写了一句$A=$R\Nasm32,读者请自行替换。

[Description]
1=Netwide assembler

[Version]
Version=2219

[CharTab]
2=0251222522222232;20-2F
3=1111111111242221;30-3F

[Open]
0="汇编源文件 (*.asm;*.inc),*.asm;*.inc"
1="资源文件 (*.rc),*.rc"
2="文本文件 (*.txt),*.txt"
3="所有文件 (*.*),*.*"
src="汇编文件 (*.asm),*.asm,asm"
hdr="头文件 (*.inc),*.inc,inc"
mod="模块 (*.asm),*.asm,asm"

[CodeMacro]
;KeyWord,InsertBeforeActiveLine,InsertAfterActiveLine
;{I}=Copy indent from keyword line
;{C}=Cr
;{S}=Space
;{T}=Tab
;{$}=Copy Proc/Struct Name
;The macros are set up to assume AutoIndent on
1=%macro,{T},{C}{I}%endmacro
2=istruc,{T},{C}{I}iend
3=struc,{T},{C}{I}endstruc

[Code]
Skip={C},%include,at,push,mov,cmp
Code=$ endp,$ proc
Const={C},$ equ
Data={C},$ db,$ dw,$ dd,$ dq,$ df,$ dt,$ byte,$ word,$ dword,$ qword,$ resd
Macro=%endmacro,%macro $
Struct=iend,istruc $
Struct2=endstruc,struc $
Label={C},$ :

[CodeBlock]
1=istruc $,iend,,,6
2=struc $,endstruc,,,14
3=[SECTION,,,,16
4=segment,,,,16

[Api]
Trig=call
Call=Nasm\nasmApiCall.api
Const=Nasm\nasmApiConst.api
Struct=Nasm\nasmApiStruct.api
Word=Nasm\nasmApiWord.api
Message=Nasm\nasmMessage.api
Inc=%include,','
Lib=

[Edit]
Font=宋体
FontHeight=-16
FontWeight=400
TxtFont=宋体
TxtFontHeight=-16
TxtFontWeight=400
TabSize=4
Backup=9
AutoSave=1
BacupPath=$P\Bak\
AutoIndent=1
ApiList=1
ApiToolTip=1
Properties=1
MouseWheel=1
SaveSize=1
Maximize=1
ApiConst=1
CodeWrite=1
TabToSpc=0
ApiStruct=1
PrnFont=宋体
PrnFontHeight=-16
PrnFontWeight=400
PrnPage=20990,29690,1000,1000,1000,1000,0
PrnOption=2,0,1,1,1
PrnColor=0,32768,8421504,255,65280,10485760,10485760,10485760,10485760,10485760,10485760,10485760,10485760,10485760,10485760,0,0,0,0,0,0
FontCharSet=134
TxtFontCharSet=134
PrnFontCharSet=134
ApiWordConv=1
ApiWordLocal=1
CodeFiles=.asm.inc.rc.tpl.rad.
FontItalic=0
TxtFontItalic=0
HexFont=新宋体
HexFontHeight=-16
HexFontWeight=400
HexFontItalic=0
HexFontCharSet=134
LnrFont=宋体
LnrFontHeight=-12
DlgFont=宋体
DlgFontHeight=-12
DlgFontWeight=400
DlgFontItalic=0
DlgFontCharSet=134
ToolFont=宋体
ToolFontHeight=-12
ToolFontWeight=400
ToolFontItalic=0
ToolFontCharSet=134
ThreadBuild=1
ChangeNotify=1
ApiShiftSpace=1
HiliteLine=0
HiliteCmnt=0
ProcsToApi=1
EnterOnTab=0
ProcInSBar=0
LnrWidth=4
LnrOnOpen=0
PageSize=66
OpenCollapsed=0
AutoBrackets=1
CodeTooltip=1
BraceMatch=({[,)}],\,

[Dialog]
Grid=1
GridX=3
GridY=3
SnapToGrid=1
ShowSize=1
SaveRC=1
SimpleProperty=0

[Error]
BookMark=3

[Paths]
$A=$R\Nasm32
$B=$A
$D=$R/AddIns 
$H=$A/Help 
$I=$A/Inc 
$L=$A/Lib 
$P=$R\Nasm\Projects
$S=$R\Nasm\Sniplets
$T=$R\Nasm\Templates
$M=$R\Nasm\Macro
$E=D:/Program Files/emu8086 

[MakeFiles]
0=.rap
1=.rc
2=.asm
3=.obj
4=.res
5=.exe
6=.def
7=.dll
8=.txt
9=.lib
10=.mak
11=.hla

[Project]
Type=Win32 App,Plat App,Dos App
Files=Asm,Inc,Rc,Def,Txt,Mak
Folders=Bak,Mod,Res
MenuMake=编译资源脚本,编译,连接,构建,构建并运行,运行,在调试器中运行,全部构建并运行,编译模块
Group=1
GroupExpand=1

[MakeDefNoProject]
MenuMake=1,1,1,1,1,1,1,1,0,0
1=rsrc.res,O,$B\GORC,rsrc.rc
2=$.obj,O,$B\NASMW -fobj,$.asm
3=$.exe,O,$B\ALINK -oPE,$.obj,\nasm\lib\win32.lib,rsrc.res
4=0,0,,$.exe
5=rsrc.obj,O,$B\CVTRES,rsrc.res
6=*.obj,O,$B\NASMW -fobj,*.asm
7=0,0,\OllyDbg\OllyDbg,$.exe
11=rsrc.res,O,$B\GORC,rsrc.rc
12=$.obj,O,$B\NASMW -fobj,$.asm
13=$.exe,O,$B\ALINK -oPE,$.obj,\nasm\lib\win32.lib,rsrc.res
14=0,0,,$.exe
15=rsrc.obj,O,$B\CVTRES,rsrc.res
16=*.obj,O,$B\NASMW -fobj,*.asm
17=0,0,\OllyDbg\OllyDbg,$.exe

[Win32 App]
Files=1,1,1,0,0
Folders=1,0,1
MenuMake=1,1,1,1,1,1,1,1,0,0
;x=FileToDelete/CheckExistsOnExit,
;(O)utput/(C)onsole/0,Command,
;MakeFile1[,MakeFile2[,MakeFile3...]]
1=4,O,$B\GORC,1
2=3,O,$B\NASMW -fobj,2
3=5,O,$B\ALINK -oPE -o $5,3,$L\win32.lib,4
4=0,0,,5
5=rsrc.obj,O,$B\CVTRES,rsrc.res
6=*.obj,O,$B\NASMW -fobj,*.asm
7=0,0,\OllyDbg\OllyDbg,5
11=4,O,$B\GORC,1
12=3,O,$B\NASMW -fobj,2
13=5,O,$B\ALINK -oPE -o $5,3,$L\win32.lib,4
14=0,0,,5
15=rsrc.obj,O,$B\CVTRES,rsrc.res
16=*.obj,O,$B\NASMW -fobj,*.asm
17=0,0,\OllyDbg\OllyDbg,5

[Plat App] 
Files=1,1,0,0,0 
MenuMake=0,1,0,1,1,1,1,1,0,0 
1=rsrc.res,O,$B/GORC,rsrc.rc 
2=$.bin,O,$B/Nasm -fbin,$.asm,-o,$.bin 
3=$.com,O,$B/Nasm -g -fbin,$.asm,-o,$.com 
4=0,0,,$.com 
5=rsrc.obj,O,$B/CVTRES,rsrc.res 
6=*.bin,O,$B/Nasm -fbin,*.asm 
7=0,0,"$E/emu8086",$.com 
11=rsrc.res,O,$B/GORC,rsrc.rc 
12=$.bin,O,$B/Nasm -fbin,$.asm 
13=$.com,O,$B/Nasm -g -fbin,$.asm,-o,$.com 
14=0,0,,$.com 
15=rsrc.obj,O,$B/CVTRES,rsrc.res 
16=*.bin,O,$B/Nasm -fbin,*.asm,-o,$.bin 
17=0,0,"$E/emu8086",$.com 

[Dos App] 
Files=1,1,0,0,0 
MenuMake=0,1,0,1,1,1,1,1,0,0 
1=rsrc.res,O,$B/GORC,rsrc.rc 
2=$.obj,O,$B/Nasm -g -fobj,$.asm 
3=$.exe,O,$B/Link,$.obj,,,,,,, 
4=0,0,,$.exe 
5=rsrc.obj,O,$B/CVTRES,rsrc.res 
6=*.obj,O,$B/Nasm -g -fobj,*.asm 
7=0,0,"$E/emu8086",$.exe 
11=rsrc.res,O,$B/GORC,rsrc.rc 
12=$.obj,O,$B/Nasm -g -fobj,$.asm 
13=$.exe,O,$B/Link,$.obj,,,,,,, 
14=0,0,,$.exe 
15=rsrc.obj,O,$B/CVTRES,rsrc.res 
16=*.obj,O,$B/Nasm -g -fobj,*.asm 
17=0,0,"$E/emu8086",$.exe

[MenuMake]
1=编译资源脚本(&C),372,M,1
2=编译(&A),116,M,2
3=连接(&L),1652,M,3
4=构建(&B),1396,M,2,3
5=-,0,M,
6=构建并运行(&G),628,M,2,3,4
7=-,0,M,
8=运行(&R),884,M,4
9=在调试器中运行(&D),580,M,7
10=-,0,M,
11=全部构建并运行(&A),1140,M,1,2,3,4
12=-,0,M,
13=编译模块(&M),0,M,6
Ver=100

[Color]
UseColor=1
Back=4144959
Fore=12632256
Bar=12550399
Cmnt=8454143
Str=16777215
Oper=2631935
C0=8454016
C1=16777088
C2=16744448
C3=12615935
C4=12615808
C5=11184640
C6=4227327
C7=16711935
C8=33488896
C9=16711808
Output=12058623
Project=12058623
Property=12058623
Dialog=8421376
CmntBack=0
StrBack=0
NumBack=0
OperBack=0
B0=4144959
B1=4144959
B2=4144959
B3=4144959
B4=4144959
B5=4144959
B6=4144959
B7=4144959
B8=4144959
B9=4144959
B10=4144959
B11=4144959
B12=4144959
B13=4144959
B14=4144959
B15=4144959
DivLine=1
NoFlicker=0
SelBack=8388608
SelText=16777215
Num=8421376
HiLine1=15777984
HiLine2=12644544
HiLine3=12632304
BarPen=8421504
LnrFontColor=8388608
Outputtext=0
Projecttext=0
Propertytext=0
Info=12644592
Infotext=0
C10=16711680
C11=16711680
C12=16711680
C13=16711680
C14=16711680
C15=16711680
CustColors=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

[KeyWords]
;Registers
C0=AH AL AX BH BL BP BX CH CL CR0 CR2 CR3 CS CX DH DI DL DR0 DR1 DR2 DR3 DR6 DR7 DS DX EAX EBP EBX ECX EDI EDX ES ESI ESP FS GS MM0 MM1 MM2 MM3 MM4 MM5 MM6 MM7 SI SP SS ST TR3 TR4 TR5 TR6 TR7 XMM0 XMM1 XMM2 XMM3
;Instructions
C1=ADC ADD AND CALL CBW CLC CLD CLI CMC CMP CMPS CMPSB CMPSW CWD DAS DEC DIV DAA ESC HLT IDIV IMUL IN INC INT INTO IRET JA JAE JB JBE JC JCXZ JE JG JGE JL JLE JMP JNA JNAE JNB JNBE JNC JNE JNG JNGE JNL JNLE JNO JNP JNS JNZ JO JP JPE JPO JS JZ LAHF LDS LEA LES LODS LODSB LODSW LOOP LOOPE LOOPEW LOOPNE LOOPNEW LOOPNZ LOOPNZW LOOPW LOOPZ LOOPZW MOV MOVS MOVSB MOVSW MUL NEG NOP NOT OR OUT POP POPF PUSH PUSHF RCL RCR RET RETF RETN ROL ROR SAHF SAL SAR SBB SCAS SCASB SCASW SHL SHR STC STD STI STOS STOSB STOSW SUB TEST WAIT XCHG XLAT XLATB XOR AAA AAD AAM AAS
;Instructions
C2=ARPL BOUND BSF BSR BSWAP BT BTC BTR BTS CDQ CLTS CMPSD CMPXCHG CWDE ENTER INS INSB INSD INSW INVD INVLPG IRETD IRETDF IRETF JECXZ LAR LEAVE LFS LGDT LGS LIDT LLDT LMSW LOCK LODSD LOOPD LOOPED LOOPNED LOOPNZD LOOPZD LSL LSS LTR MOVSD MOVSX MOVZX OUTS OUTSB OUTSD OUTSW POPA POPAD POPFD PUSHA PUSHAD PUSHD PUSHFD PUSHW REP REPE REPNE REPNZ REPZ SCASD SETA SETAE SETB SETBE SETC SETE SETG SETGE SETL SETLE SETNA SETNAE SETNB SETNBE SETNC SETNE SETNG SETNGE SETNL SETNLE SETNO SETNP SETNS SETNZ SETO SETP SETPE SETPO SETS SETZ SGDT SHLD SHRD SIDT SLDT SMSW STOSD STR VERR VERW WBINVD XADD
;FPU Instructions
C3=F2XM1 FABS FADD FADDP FBLD FBSTP FCHS FCLEX FCOM FCOMP FCOMPP FCOS FDECSTP FDISI FDIV FDIVP FDIVR FDIVRP FENI FFREE FIADD FICOM FICOMP FIDIV FIDIVR FILD FIMUL FINCSTP FINIT FIST FISTP FISUB FISUBR FLD FLD1 FLDCW FLDENV FLDENVD FLDENVW FLDL2E FLDL2T FLDLG2 FLDLN2 FLDPI FLDZ FMUL FMULP FNCLEX FNDISI FNENI FNINIT FNOP FNSAVE FNSAVED FNSAVEW FNSTCW FNSTENV FNSTENVD FNSTENVW FNSTSW FPATAN FPREM FPREM1 FPTAN FRNDINT FRSTOR FRSTORD FRSTORW FSAVE FSAVED FSAVEW FSCALE FSETPM FSIN FSINCOS FSQRT FST FSTCW FSTENV FSTENVD FSTENVW FSTP FSTSW FSUB FSUBP FSUBR FSUBRP FTST FUCOM FUCOMP FUCOMPP FWAIT FXAM FXCH FXTRACT FYL2X FYL2XP1
;MMX Instructions
C4=EMMS MOVD MOVQ PACKSSDW PACKSSWB PACKUSWB PADDB PADDD PADDSB PADDSW PADDUSB PADDUSW PADDW PAND PANDN PCMPEQB PCMPEQD PCMPEQW PCMPGTB PCMPGTD PCMPGTW PMADDWD PMULHW PMULLW POR PSLLD PSLLQ PSLLW PSRAD PSRAW PSRLD PSRLQ PSRLW PSUBB PSUBD PSUBSB PSUBSW PSUBUSB PSUBUSW PSUBW PUNPCKHBW PUNPCKHDQ PUNPCKHWD PUNPCKLBW PUNPCKLDQ PUNPCKLWD PXOR
;XMM/K3D Instructions
C5=#define #include ACCELERATORS ALT AUTOCHECKBOX AUTORADIOBUTTON BEGIN BITMAP BLOCK CAPTION CLASS COMBOBOX CONTROL CURSOR DIALOGEX DISCARDABLE EDITTEXT EXSTYLE FILEOS FILETYPE FILEVERSION FONT GROUPBOX ICON LISTBOX LTEXT MENU MENUITEM NOINVERT POPUP PRODUCTVERSION PUSHBUTTON SEPARATOR SHIFT STRINGTABLE STYLE VALUE VERSIONINFO VIRTKEY
C6=BYTE DB DD DQ DT DW DWORD OWORD QWORD REAL10 REAL4 REAL8 SBYTE SDWORD SWORD TBYTE WORD
;NASM Keywords (non-code producing)
C7=%DEFINE %ENDMACRO %INCLUDE %MACRO AT CODE DATA ENDSTRUC EQU EXTERN IEND IMPORT ISTRUC RESB RESD RESW SECTION STRUC USE32
;NASM Keywords (code producing)
C8=CALL
;NASM Macro Ops
C9=
C10=
C16=

[ReallyRad]
AddDlg=1
AddMnu=1
AddRes=1
AddVer=1
CtlClk=1
MnuSel=1
AddFile=1
AddFolder=1
CtlNme=1
AddStr=1
[MenuMacro]
Ver=100

然后新建一个plat项目,写入第一章的代码:

	org	07c00h			; 告诉编译器程序加载到7c00处
	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	call	DispStr			; 调用显示字符串例程
	jmp	$			; 无限循环
DispStr:
	mov	ax, BootMessage
	mov	bp, ax			; ES:BP = 串地址
	mov	cx, 23			; CX = 串长度
	mov	ax, 01301h		; AH = 13,  AL = 01h
	mov	bx, 000ch		; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
	mov	dl, 0
	int	10h			; 10h 号中断
	ret
BootMessage:		db	"Hello, OS world! Hankcs"
times 	510-($-$$)	db	0	; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 	0xaa55				; 结束标志

一键编译链接运行,得到bin文件和com文件,在DosBox下是这个效果:

注意上图不协调的黑色行,应该可以显示出字符串,但是没有显示出来,只显示出了黑底没显示红字。

按照作者的指导,将程序性加载地址改为org 0100h后,就可以看到效果了:

	org	0100h			
	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	call	DispStr			; 调用显示字符串例程
	jmp	$			; 无限循环
DispStr:
	mov	ax, BootMessage
	mov	bp, ax			; ES:BP = 串地址
	mov	cx, 23			; CX = 串长度
	mov	ax, 01301h		; AH = 13,  AL = 01h
	mov	bx, 000ch		; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
	mov	dl, 0
	int	10h			; 10h 号中断
	ret
BootMessage:		db	"Hello, OS world! Hankcs"
times 	510-($-$$)	db	0	; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 	0xaa55				; 结束标志

还可以利用emulator来调试:

用作者提供的FloppyWriter.exe将项目目录下的bin文件写入代码目录下的a.img,然后用VMWare新建一个虚拟机载入a.img,看到屏幕上的红字了:

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » Win64下集成RadASM+nasm编写操作系统

评论 3

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    你好,请问倒数第二张图,emulator是什么软件 ,只用“emulator”搜不出什么有用信息来

    陪我流浪8年前 (2016-05-12)回复
    • emulator是模拟器的意思,也就是各种仿真器,比如bochs,qemu等

      核爆下的小强8年前 (2016-07-30)回复
      • 单词倒是知道意思,但这词太通用,搜不出东西。在别的论坛上有人认识,是emu8086

        陪我流浪8年前 (2016-07-31)回复

我的作品

HanLP自然语言处理包《自然语言处理入门》