- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试将字节 0xff
写入位于 0x378
的并行端口。它编译和链接没有问题,但在 OUTSB
指令处出现段错误。
section .text
global _start
_err_exit:
mov eax, 1
mov ebx, 1
int 80h
_start:
mov eax, 101 ; ioperm
mov ebx, 0x378 ; Parallel port addr
mov ecx, 2 ; number of bytes to 'unlock'
mov edx, 1 ; enable
int 80h
mov esi, 0xff
mov dx, 0x378
outsb
mov eax, 1 ; exit
mov ebx, 0
int 80h
如果我用 GDB 单步执行它并在 OUTSB
指令之前检查寄存器,看起来 DX 寄存器中没有任何内容?还是 32 位的 dx
== edx
?
(gdb) info registers
eax 0x0 0
ecx 0x2 2
edx 0x378 888
ebx 0x378 888
esp 0xffffd810 0xffffd810
ebp 0x0 0x0
esi 0xff 255
edi 0x0 0
eip 0x8048090 0x8048090 <_start+36>
eflags 0x246 [ PF ZF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
我在这里做错了什么?
(关于 OUTS 指令的信息:http://siyobik.info/main/reference/instruction/OUTS%2FOUTSB%2FOUTSW%2FOUTSD)
编辑:
程序的 C 版本工作:
int main(int argc, char *argv[])
{
int addr = 0x378;
int result = ioperm(addr,5,1);
outb(0xff, addr);
}
最佳答案
该代码存在许多问题。首先,您似乎忘记了 OUTSB
是一条特权指令,即它只有在调用进程具有 ring 0 访问权限时才能执行,即它是内核代码的一部分。据我所知,Linux 中唯一可以访问特权指令的代码是内核本身及其加载的模块。当您尝试从非特权段执行特权指令时,所有其他进程都会给您一个Segmentation fault
(这实际上是一个 General Protection Fault
由 CPU 发出信号)代码。不过,我不知道调用 ioperm
系统调用会如何影响它。
其次,OUTSB
从ESI
指定的内存位置写入一个字节到DX
中的I/O 端口。在这种情况下,您要告诉处理器将数据从位置 0xff
写入端口,进程肯定无法访问该端口。您可以通过简单地更改代码以使用 OUT
指令来简化它,因为 OUTSB
更适合与 REP
前缀一起使用。试试这个:
mov al, 0xff
out 0x378, al
这会将 al
中的字节输出到直接操作数指定的 I/O 端口,在本例中为 0x378
。
告诉我结果如何。
关于Linux NASM OUTSB 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9422097/
我正在尝试将字节 0xff 写入位于 0x378 的并行端口。它编译和链接没有问题,但在 OUTSB 指令处出现段错误。 section .text global _start _er
我是一名优秀的程序员,十分优秀!