我在下面的程序中遇到分段错误 这是用于将光标设置在屏幕的左上角。但为什么我在这个程序上遇到分段错误? 谢谢你的回复。
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。
答案 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