如何用汇编语言读取内存值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用汇编语言读取内存值相关的知识,希望对你有一定的参考价值。
,例如VC的_ASM
比如我要读取45d541的地址该如何写?
还有一点不确定,用汇编读取的内存地址能赋值给变量么?
MOV AX,[8000] ;立即数寻址,将AX寄存器中放入偏移地址8000中的内容
MOV AX,[SI] ;寄存器寻址,将SI寄存器中的值作为地址,SI寄存器中存放的地址中 内容送到AX寄存器中。另外,任何通用寄存
(AX,BX,CX,DX,SI,DI,BP,SP)都可以放入方括号[]中行寻址
NUMBER DW 1234H ;变量地址定义
...
MOV AX,[NUMBER] ;将NUMBER的地址进行寻址,然后将地址内的内容送入AX寄存 器中
需要注意的是,如果需要往立即数地址中直接写入或读取数据,则需要添加数据的大小标识符,否则编译器会产生错误。如下:
MOV [8000],1234H ;错误的指令!
MOV WORD PTR [8000],1234H ;正确,往偏移地址8000的内存位置中放入WORD类型的数据1234H 参考技术A [方法一] 在数据段中定义数据,例如:
DATA SEGMENT
ORG 100H
DAT1 DB 18H ;将数据18H写入数据段偏移址为100H的内存
DATA ENDS
;
[方法二] 在代码段中用数据传送指令,例如:
CODES SEGMENT
ASSUME CS:CODES
START:
MOV AL, 25H
MOV [200],AL ;将AL中的数据25H写入数据段偏移址为200H的内存单元
;......
CODES ENDS
END START 参考技术B 你说的应该是win32吧 保护模式下
读取用 mov eax,[45d541] ;默认是DS段
如果你有45d541地址空间的写权限 就能赋值 mov ptr dword [45d541],eax 参考技术C 你说的应该是win32吧 保护模式下
读取用 mov eax,[45d541] ;默认是DS段
如果你有45d541地址空间的写权限 就能赋值 mov ptr dword [45d541],eax
如何用高级语言对操作系统进行编码?
我刚刚开始涉足操作系统领域,并且我了解到进程具有一定的内存空间,它们可以处理这些内存空间,这些内存空间由操作系统处理。我不太了解用c和c ++等高级语言编写的操作系统如何获得这种内存管理功能。
您已经捕获了该错误,并且无法治愈:-)
您用于编写操作系统的语言与操作系统的运行方式几乎没有关系。是的,大多数人使用C / C ++,但还有其他人。至于语言,您确实需要一种可以让您直接与计划管理的硬件进行通信的语言,而组装是该部分的主要选择。但是,这还不到整个项目的5%。
您编写的代码不得依赖任何现有操作系统。即:您必须自己编写所有函数的代码,或调用现有的库。但是,必须编写这些现有库,以使它们不依赖任何其他内容。
一旦有了基础,就可以用您选择的任何语言来编写操作系统,而汇编中的次要部分是高级语言所不允许的。实际上,在64位代码中,某些编译器不再允许行内汇编,因此这使我上面提到的5%更像是15%。
找出您想做的事,然后找出是否可以用选择的语言来完成。例如,主要的操作系统组件可以用C编写,而实际的处理器管理(中断等)必须在汇编中完成。您的引导代码也必须是汇编的,至少其中大多数是汇编的。
作为mentioned in a different post,我有一些您可能想看的early example code。引导是通过汇编完成的,而传统的BIOS和EFI加载程序代码大多是C代码。
为了阐明fysnet的答案,您必须至少使用一些汇编程序的原因是,您只能在C / C ++中(通过指针)显式访问可寻址内存,而硬件寄存器(例如程序计数器或堆栈指针)通常没有内存地址。不仅如此,而且某些寄存器还必须使用依赖于CPU体系结构的特殊指令来操作,而且这也只能用机器语言来实现。
我不太了解用c和c ++等高级语言编写的操作系统如何获得这种内存管理功能。
如上所述,根据体系结构,这可以通过具有管理MMU,TLB等的特殊指令来实现。INVLPG是x86体系结构中此类指令的一个示例。请注意,拥有一条需要内核特权的特殊指令可能是在硬件中以安全方式实现此功能的最简单方法,因为这足以检查CPU是否处于内核模式,以确定该指令是否可以被执行。是否执行。
编译器会为您将高级语言转换为asm /机器代码,因此您不必自己编写asm。您选择了一种可以按您希望的操作系统处理内存的编译器。例如使用调用堆栈进行自动存储,而不是隐式调用malloc
/ free
(因为那些在内核中将不存在)。
要将编译后的C / C ++链接到内核,通常必须了解有关它所针对的ABI以及工具链(尤其是链接器)的更多信息。
ISO C标准将实现细节视作黑匣子。但是人们使用的低级东西的实际编译器以内核程序员所依赖的众所周知的方式工作(即做出预期的/有用的实现选择),就将代码和静态数据编译为可以链接为单个块的连续块而言内核可执行文件,可以全部加载为一个块。
关于实际管理系统的内存,您可以自己编写代码来做到这一点,并在必要时使用一些内联汇编,以用于诸如invlpg
之类的特殊指令,以及其他答案。]
入口点(执行开始的地方,通常将以纯asm格式编写)
,以建立带有指向它的堆栈指针寄存器的调用栈。并设置虚拟内存等,以便可执行代码,读取/写入数据以及读取只读数据。在跳转到任何已编译的C代码之前,所有这些都必须要做。您跳到的第一个C可能是更多的内核初始化代码,例如初始化数据结构以供分配器管理静态代码/数据尚未使用的所有内存。创建堆栈并将代码/数据映射到内存是一种通常在启动用户空间程序时由操作系统by
完成的设置。编译器发出的汇编将假定代码,静态数据和堆栈都已经存在。以上是关于如何用汇编语言读取内存值的主要内容,如果未能解决你的问题,请参考以下文章