[英]Linux NASM OUTSB SegFault
I'm trying to write byte 0xff
to the parallel port at 0x378
. 我正在尝试将字节
0xff
写入并行端口0x378
。 It compiles and links without issue, but segfaults at the OUTSB
instruction. 它可以毫无问题地进行编译和链接,但是会在
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
If I step through it with GDB and check the registers just before the OUTSB
instruction, it doesn't look like there is anything in the DX register? 如果我使用GDB逐步检查并检查
OUTSB
指令之前的寄存器,那么看起来DX寄存器中没有任何内容吗? or dx
== edx
in 32bit? 或
dx
== edx
(32位)?
(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
What am I doing wrong here? 我在这里做错了什么?
(info on the OUTS instructions: http://siyobik.info/main/reference/instruction/OUTS%2FOUTSB%2FOUTSW%2FOUTSD ) (有关OUTS指令的信息: http ://siyobik.info/main/reference/instruction/OUTS%2FOUTSB%2FOUTSW%2FOUTSD)
EDIT: 编辑:
The C version of the program works: 该程序的C版本有效:
int main(int argc, char *argv[])
{
int addr = 0x378;
int result = ioperm(addr,5,1);
outb(0xff, addr);
}
There is a number of issues with that code. 该代码存在许多问题。 Firstly, you seem to forget that
OUTSB
is a privileged instruction, ie it can be executed only if the calling process has ring 0 access, ie it's a part of the kernel code. 首先,您似乎忘记了
OUTSB
是特权指令,即只有在调用进程具有ring 0访问权限(即它是内核代码的一部分)时才能执行。 As far as I'm aware, the only code in Linux that has access to privileged instructions is the kernel itself, and the modules that it loads. 据我所知,Linux中唯一可以访问特权指令的代码是内核本身及其加载的模块。 All the other processes will give you a
Segmentation fault
(which is actually a General Protection Fault
signalled by the CPU) when you try to execute a privileged instruction from a nonprivileged segment of code. 当您尝试从非特权代码段执行特权指令时,所有其他进程都会给您带来
Segmentation fault
(实际上是CPU发出的General Protection Fault
)。 I don't know how calling the ioperm
syscall influences that, though. 不过,我不知道调用
ioperm
syscall会如何影响这一点。
Secondly, OUTSB
writes a byte from a memory location specified by ESI
to the I/O port in DX
. 其次,
OUTSB
从ESI
指定的存储位置向DX
的I / O端口写入一个字节。 In this case, you're telling the processor to write data to the port from location 0xff
, to which the process surely doesn't have access. 在这种情况下,您要告诉处理器将数据从位置
0xff
写入端口,该进程肯定无法访问该位置。 You can simplify that by simply changing the code to use the OUT
instruction, since OUTSB
is rather meant to be used with the REP
prefix. 您可以通过简单地更改代码以使用
OUT
指令来简化此操作,因为OUTSB
而是与REP
前缀一起使用的。 Try this : 尝试这个 :
mov al, 0xff
out 0x378, al
This outputs the byte in al
to the I/O port specified by the immediate operand, in this case 0x378
. 它将
al
的字节输出到立即操作数指定的I / O端口,在这种情况下为0x378
。
Let me know how that turned out. 让我知道结果如何。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.