第一次写这么长的汇编代码,可惜这个错误我实在排不了
我是学习大灰狼老师的视频,跟着敲,其他的没问题,他能在linux下nasm中编译通过,我就出了三个语法错误,代码:程序代码:
;一个非常简单的启动程序,在屏幕中央打印一行代码 [BITS 16] ;告诉编译器是在16下编译 org 07c00h ;org,明确告诉编译器程序的开始段地址是7c00h ;而不是原来的0000 ;int汇编指令 后面跟上你要呼叫的中断号 eg:int 10h jmp main gdt_table_start: gdt_null: dd 0h dd 0h ;inter规定段描述表的第一个表项必须为零 gdt_data_addr equ $-gdt_table_start ;数据段 gdt_data: dw 07FFH ;段界限 dw 0h ;段基地址0-18位 db 0h ;段基地址19-23位 db 10010010b ;段描述符的第六个字节属性(数据段) db 11000000b ;段描述符的第七个字节属性 db 0 ;段描述符的最后一个字节也就是段基地址 gdt_video_addr equ $-gdt_table_start ;描述显存地址空间的段描述符 gdt_video: dw 0ffh ;显存段界限大小1M dw 8000h;段基地址0-18 db 0bh; db 10010010b; db 11000000b; db 0; gdt_code_addr equ $-gdt_table_start ;代码段 gdt_code: dw 07ffh ;段界限 dw 1h ;段基地址0-18位 db 80h ;段基地址19-23位 db 10011010b ;段描述符的第六个字节属校(代码段) db 11000000b ;段描述符的第七个字节属性 db 0 ;段基地址的第二部分 gdt_table_end: ;表示段描述符的结束 gdtr_addr: dw gdt_table_end-gdt_table_start-1 ;段描述表长度 dd gdt_table_start ;段描述符表基地址 lgdt [gdtr_addr] ;让CPU读取gdtr_addr所指向内存的内容保存到GDT寄存器中 ;A20地址线问题。必须开启,这是切换到保护模式的必备条件 main: enable_a20: in al,92h ;往92号端口写,以开启A20地址线 or al,00000010b ;为了实现,就拿32位来和这个数据进行或 out 92h,al ;从92号端口读 cli ;在转入保护模式之前,要废除中断向量表,进入保护模式后,再有系统创建该表 ;怎么进入保护模式呢?怎么设置分页或者分段管理模式呢?仅需设置CR0寄存器 ;设置cr0寄存器的第一位为1 mov eax,cr0 ;将cr0的内容拷贝进32位的寄存器 or eax,1 ; mov cr0,eax ;万事俱备只欠东风,下一步就该跳转到保护模式了 ;跳转 jmp gdt_code_addr:0 ;有三种jmp,这里选择了远跳转 ;接下来是在保护模式下编程,注意不再是16位,而是32位了 [BITS 32] ; 告诉编译器是在32位下编译 data_32: db "hello word" code_32: mov ax,gdt_data_addr mov ds,ax mov ax,gdt_video_addr mov gs,ax mov cx,11 mov edi,(80*10+12)*2 ;在平幕中央显示 mov bx,0 mov ah,0ch s: mov al,[ds:bx] mov [gs:edi],al mov [gs:edi+1],ah inc bx add edi,2 loop s jmp $ times 510-($-$$) db 0 dw 0aa55h mov ax,cs mov es,ax mov bp,msgstr ;es:bp 指向的内容就是我们要显示的字符串地址了 mov cx,12 ;字符串长度 mov dh,12 ;行号 mov dl,36 ;列号 mov bh,0 ;页号,页数 mov al,1 ;显示方式 字符串 mov bl,0ch ;字体的属性,颜色背景之类 mov ah,13h ;明确调用13h子程序 msgstr: db "hello my os!" int 10h ;呼叫BIOS的中断,以实现上面的工能 times 510-($-$$) db 0 ;重复N次,每次填充值为零 dw 55aah ;512K的最后两字 jmp $ ;不让程序结束,不断跳转到当前位置以形成死循环,如果程序一结束,那么就达不到目的了
错误是如下提示
[shi@localhost c_programming]$ nasm boot.asm -o boot.bin
boot.asm:32: error: symbol `gdt_table_end' undefined
boot.asm:74: error: symbol `msgstr' undefined
boot.asm:79: error: TIMES value -17 is negative
[shi@localhost c_programming]$
[shi@localhost c_programming]$
[shi@localhost c_programming]$
但是我搞不懂这个怎么会是这样, gdt_table_end 怎么就会没定义呢?求求大神指点一下,万分感谢!