X86 这里是$0x1a寄存器吗? 函数的汇编程序代码转储read@plt: 0x0000000000402458:jmpq*0x2b4f72(%rip)#0x6b73d0 0x000000000040245e:pushq$0x1a 0x0000000000402463:jmpq 0x4022a8

X86 这里是$0x1a寄存器吗? 函数的汇编程序代码转储read@plt: 0x0000000000402458:jmpq*0x2b4f72(%rip)#0x6b73d0 0x000000000040245e:pushq$0x1a 0x0000000000402463:jmpq 0x4022a8,x86,disassembly,X86,Disassembly,有人知道吗 顺便说一句,read如何知道他到达了文件的末尾?不,这是一个立即值pushq将值推送到堆栈上,堆栈可能是一个寄存器,但您会发现它们由操作数表示,如%rbx $0x1a是一个立即值-您也可以通过该指令的长度(五个字节,从x+6到x+10)来判断这一点。pushq指令能够推送寄存器、内存内容(64位)或32位立即数(符号扩展到64位) 在这种情况下,五个字节是操作码0x68以及要推送的32位值。如果要检查内存,它可能看起来像0x68 0x1a 0x00 0x00 0x00 0x00 不要

有人知道吗


顺便说一句,
read
如何知道他到达了文件的末尾?

不,这是一个立即值
pushq
将值推送到堆栈上,堆栈可能是一个寄存器,但您会发现它们由操作数表示,如
%rbx

$0x1a
是一个立即值-您也可以通过该指令的长度(五个字节,从
x+6
x+10
)来判断这一点。
pushq
指令能够推送寄存器、内存内容(64位)或32位立即数(符号扩展到64位)

在这种情况下,五个字节是操作码0x68以及要推送的32位值。如果要检查内存,它可能看起来像
0x68 0x1a 0x00 0x00 0x00 0x00

不要被这些代码愚弄,它根本不是“真正的”读取调用。它是一个存根,用于在运行时修复引用,其中代码段可以在处理器之间共享,甚至在不同的基址上


PLT是每个进程占用的一个小存根,它第一次跳转到真正的共享代码,在进程中进行自我修复,以便将来直接跳转到那里。有关此过程的解释,请参阅。

寄存器(通常)没有内存位置,它们是CPU寄存器。

尚未提及,但前导的$符号表示常量。在查看程序集转储时就这么简单


一个简单的陷阱:当查看大量未链接的二进制文件时,不要被0x00000000所愚弄。如果没有前导$,这些是链接器重定位,而不是常量0值。

因此,
$0x1a
确实是一个寄存器,
%rbx
具体而言?不,
$0x1a
不是寄存器,它是十六进制
1a
的立即值(十进制26)Windows及其前身的文件结束指示符。因此,我可以想象是否最终会有其他类似的调用转到同一个系统调用,但参数不同,如
$0x1a
?请不要将
read
函数误认为是系统调用。syscall是使用int80或更新的sysenter(或者根据体系结构使用另一种方法)的内核接口
read()
对于内核程序员来说只是另一个用户区(sys\u read是它最终得到的系统调用)。至于其他调用,它们在PLT中有自己的位置。EOF在stdio.h中不是定义为
-1
吗?当我们说register时,我们指的是CPU寄存器以外的任何东西,对吗?不,“寄存器”可以指其他东西,具体取决于上下文,但如果上下文是低级汇编,那么是的,它几乎总是CPU寄存器。
Dump of assembler code for function read@plt:
0x0000000000402458 <read@plt+0>:    jmpq   *0x2b4f72(%rip)        # 0x6b73d0 <_GLOBAL_OFFSET_TABLE_+232>
0x000000000040245e <read@plt+6>:    pushq  $0x1a
0x0000000000402463 <read@plt+11>:   jmpq   0x4022a8