中断10h无法正常工作

时间:2014-04-15 16:00:06

标签: assembly architecture x86 interrupt interrupt-handling

我在下面的程序中遇到分段错误 这是用于将光标设置在屏幕的左上角。但为什么我在这个程序上遇到分段错误? 谢谢你的回复。

section .text
global main
main:
    mov ah, 2
    mov bh, 1
    mov dh, 0
    mov dl, 0
    int 10h

我认为问题是我正在使用的保护模式。这是一个16位指令,我在32位机器上尝试这个!我是对的吗?

我在Linux Ubuntu发行版32位中运行该程序。处理器是AMD C-60。

2 个答案:

答案 0 :(得分:3)

BIOS中断是16位代码。您的操作系统已将CPU置于32位保护模式。硬件将允许切换回16位实模式(有跳转的箍)但操作系统不允许它。如果确实不会受到“保护”。它受到美国“保护”,我的朋友!

我认为您可能想要研究的是“vt100”终端仿真。根据权利,“健壮”程序将查询“termcaps”文件,以确保vt100仿真在尝试使用之前可用。我的经验是它“通常”可以在“桌面Linux”盒子上使用,所以我只是假设它在那里。如果我们认为错误的话,可能发生的最坏情况(我认为)是屏幕上的垃圾。

此示例并不完全符合您的要求。它保存当前光标位置(领主知道位置),将光标移动到新位置,打印消息,然后返回原始光标位置。你需要查找“主光标”命令(“ESC [h”?lookitup)。只需将其写入stdout,与“hello world”相同。你也可以得到颜色和东西。

; nasm -f elf32 mygem.asm
; ld -o mygem mygem.o -melf_i386

global _start

section .data
savecursor db 1Bh, '[s'
.len equ $ - savecursor

unsavecursor db 1Bh, '[u'
.len equ $ - unsavecursor

getcursor db 1Bh, '[6n'
.len equ $ - getcursor

setcursor db 1Bh, '[10;20H'
.len equ $ - setcursor

msg db "Hello, new cursor position!"
.len equ $ - msg

section .text
_start:

mov ecx, savecursor
mov edx, savecursor.len
call write_stdout


mov ecx, setcursor
mov edx, setcursor.len
call write_stdout

mov ecx, msg
mov edx, msg.len
call write_stdout

mov ecx, unsavecursor
mov edx, unsavecursor.len
call write_stdout

exit:
mov eax, 1
xor ebx, ebx
int 80h

;------------------------
write_stdout:    
push eax
push ebx
mov eax, 4
mov ebx, 1
int 80h
pop ebx
pop eax
ret
;---------------------

答案 1 :(得分:0)

尝试以下方法:

org 100h
section .text
global main
main:
    mov ah, 2
    mov bh, 1
    mov dh, 0
    mov dl, 0
    int 10h

请阅读this

  

这个组织100h实际上告诉程序集我们的程序将从那里开始   偏移100h。为什么这有必要?这是因为所有正在运行的程序   有过程控制块(PCB)。这是件好事   操作系统来管理东西,所以,对我们来说不是更好   除非你做高级的事情,否则会干扰它。在那之后,我们   有一个跳,对吗?然后在跳转之后,将所有数据放入,   对?这就是我们应对这种混乱的方式。无条件跳跃   确保数据空间,以便它不会干扰代码。   反之亦然。通常是代码干扰的情况   数据,它会导致死机,蓝屏死机等, - 再加上    - 除非你是一个知道你正在做什么的集会大师(比如做一些自我修改的代码和类似的神秘技巧)。


对于Linux,你应该只使用系统调用this is a well documented tutorial,你在eax中输入sys call的数字并跳转到它/切换到内核模式int 80h

section .data
    hello:     db 'Hello world!',10    ; 'Hello world!' plus a linefeed character
    helloLen:  equ $-hello             ; Length of the 'Hello world!' string
                                       ; (I'll explain soon)

section .text
    global _start

_start:
    mov eax,4            ; The system call for write (sys_write)
    mov ebx,1            ; File descriptor 1 - standard output
    mov ecx,hello        ; Put the offset of hello in ecx
    mov edx,helloLen     ; helloLen is a constant, so we don't need to say
                         ;  mov edx,[helloLen] to get it's actual value
    int 80h              ; Call the kernel

    mov eax,1            ; The system call for exit (sys_exit)
    mov ebx,0            ; Exit with return code of 0 (no error)
    int 80h