Assembly 可以在8086汇编中操作指令指针吗?
我想知道我是否可以在8086汇编中操作(读取和更改)指令指针(IP)的值 比如说,Assembly 可以在8086汇编中操作指令指针吗?,assembly,x86-16,Assembly,X86 16,我想知道我是否可以在8086汇编中操作(读取和更改)指令指针(IP)的值 比如说, 假设IP当前正在存储0200h。我想读取此值并将其更改为其他值,例如4020h。我该怎么做呢?如果要将指令指针设置为已知值,例如十六进制值4020h,可以直接跳到该地址: jmp 4020h 或者,如果某个内存位置,myVariable保存了要存储在IP中的值,则可以执行间接跳转: jmp [myVariable] jmp(间接或直接)的结果修改指令指针 读取指令指针有问题。在Linux上定位独立代码,使用一
假设IP当前正在存储
0200h
。我想读取此值并将其更改为其他值,例如4020h
。我该怎么做呢?如果要将指令指针设置为已知值,例如十六进制值4020h,可以直接跳到该地址:
jmp 4020h
或者,如果某个内存位置,myVariable
保存了要存储在IP
中的值,则可以执行间接跳转:
jmp [myVariable]
jmp(间接或直接)的结果修改指令指针
读取指令指针有问题。在Linux上定位独立代码,使用一组类似以下的代码:
call getIP
与
有关读取IP的其他方法,请参阅。相关:(我更新了被接受的答案,使其不那么糟糕,并且涵盖了32位和64位,因为这是阅读IP的标准问答。没有提到写IP,因为这是一种概念上的理解:写IP是一种跳跃,但您的代码可能在不知道加载位置的情况下运行,所以用例完全不同不一样。)
还有一个近乎重复的问题:询问为什么RIP/EIP/IP不直接公开以用于在AX等整数寄存器上工作的指令(即为什么添加IP,AX
不作为间接跳转)TL:DR:像ARM这样的一些ISA确实将程序计数器公开为一个整数寄存器,但x86只有很少的寄存器,在机器代码中对IP使用一个寄存器编码会去掉一个通用整数寄存器
您可以使用
jmp
或call
直接编写IP
,但只能通过call
推送来读取
(从技术上讲,call
不是读取IP
的唯一选项。您可以使用int
或其他中断,让中断处理程序在iret
之前查看上下文,但这与call
的想法相同,只是更复杂、更慢。)
在位置相关代码中,每个指令的地址在链接时都是已知的。您可以将任何标签的地址用作立即常数或寻址模式的一部分。例如
mov ax, $ ; ax = address of the start of the MOV instruction (NASM syntax)
或
假设IP当前正在存储
0200h
我想读取此值并将其更改为其他值,例如4020h
。我该怎么做
拨打4020h
在给定当前IP的情况下,汇编程序将计算出要使用的rel16
置换量。(或者,如果您希望以位置无关的方式跳转到固定的IP
值,您可以将4020h
放入寄存器并调用ax
)(相对于cs
的偏移量,因此仍然不是绝对地址。为此,您需要一个远呼叫
,并且可以使用ptr16:16
绝对直接,将地址作为立即数。)
旧值(+调用指令的长度)将位于堆栈上,4020h
处的代码可以用pop
弹出(或者用ret
弹出回IP),或者用mov
加载
一般来说,避免错误匹配
调用
/返回
(即,不要只将返回地址弹出
到寄存器中,然后使用jmp
返回)。这将导致分支预测失误,因为返回地址预测器堆栈不平衡。(和)
在比PIII更新的CPU上,调用next\u insn
/pop ax
是有效的,因为。请参阅
@mksteve建议调用执行mov bx[sp]
/ret
的函数,而不是只调用next\u指令
/pop bx
,这在早期的Intel P6系列CPU(如PPro)上很好。但请注意[sp]
不是一种有效的16位寻址模式,因此这在16位中显得格外笨重。如果您真的想在16位代码中使用,可能pop-ax
/push-ax
/ret
会让您的工作更轻松
在64位代码中,您可以更直接地读取RIP的当前值:
lea-rax,[RIP]
。这更常用于静态数据的位置独立寻址。例如lea-rax,[rel-my_-table]
或添加dword[rel-global_-counter],2
将告诉汇编器+链接器确定使用什么rel32
来达到所需的符号。这在可执行文件或动态库中起作用,即使库加载在不同的地址,代码和数据之间的距离也是恒定的。@Doda这没有问题。调用wheremi:POP AX,JMPAX@Doda阅读9086用户手册了解体系结构,阅读汇编程序手册了解说明。然后您将能够理解mksteve的答案并对其进行表决。ATM,在得到一个好的答案后,您似乎在问一些无关的问题。JMP指令直接更改IP寄存器的值-仅此而已。IP寄存器不会更改oes在内存映射中没有地址。0x1234只是一个用作示例的值。您提出的问题毫无意义。请阅读手册。在询问有关说明详细信息之前,您需要了解体系结构和计算机的工作方式。@Doda-处理否决票的方法是发表新文章并获得否决票。:-)投票被否决的一个可能的解释是,一些人知道MOV IP,X
并没有丢失,只是拼写了JMP X
,你也许可以通过阅读英特尔的手册来发现这一点。@Doda你被否决是因为你问了一个问题,这个问题可以用谷歌或通过查看e手册。没有办法摆脱否决票。不要删除问题,但下次请进行一些研究
mov ax, $ ; ax = address of the start of the MOV instruction (NASM syntax)
mov ax, label ; or MASM: mov ax, OFFSET label
label: