完整指令在x64 asm代码中需要的最大字节数是多少?
像跳转到地址这样的东西可能占用多达9个字节我想:FF 00 00 00 00 11 12 3F 1F但我不知道这是否是x64指令可以使用的最大字节数
在Intel 64架构中,有rax..rdx寄存器,它们只是A..D通用寄存器.
但是也有一些名为rsi和rdi的寄存器,它们是"源索引"和"目标索引"寄存器.为什么这些寄存器有实际名称(与A等相比)?
"源索引"和"目标索引"实际上意味着什么?是否有一些惯例说这些寄存器应该在特定情况下使用?
我正在查看我的程序的解散(因为它崩溃了),并注意到很多
xchg ax, ax
Run Code Online (Sandbox Code Playgroud)
我用谷歌搜索它,发现它本质上是一个小鸟,但为什么visual studio会做一个xchg而不是noop?
该应用程序是由Visual Studio编译的C#.NET3.5 64位应用程序
我有以下makefile
CXXFILES = pthreads.cpp
CXXFLAGS = -O3 -o prog -rdynamic -D_GNU_SOURCE -L./libmine
LIBS = -lpthread -ldl
all:
$(CXX) $(CXXFILES) $(LIBS) $(CXXFLAGS)
clean:
rm -f prog *.o
Run Code Online (Sandbox Code Playgroud)
我试图将./libmine库包含在内CXXFLAGS,但似乎它不是包含静态库的正确方法,因为当我编译程序时,我得到许多未定义的引用错误.那么实际上在makefile中包含静态库的正确方法是什么?
在运行我用汇编编写的程序时,我收到Illegal instruction错误.有没有办法知道哪个指令导致错误,没有调试,因为我正在运行的机器没有调试器或任何开发系统.换句话说,我在一台机器上编译并在另一台机器上运行.我无法在我正在编译的机器上测试我的程序,因为它们不支持SSE4.2.我正在运行程序的机器确实支持SSE4.2指令.
我想这可能是因为我需要告诉汇编程序(YASM)识别SSE4.2指令,就像我们通过传递-msse4.2标志一样使用gcc .或者你认为这不是原因吗?知道如何告诉YASM识别SSE4.2指令吗?
也许我应该捕获SIGILL信号然后解码SA_SIGINFO以查看程序执行什么样的非法操作.
我有一个由工具生成的x86_64架构的gnu汇编程序代码,并且有以下指令:
movq %rsp, %rbp
leaq str(%rip), %rdi
callq puts
movl $0, %eax
Run Code Online (Sandbox Code Playgroud)
我找不到关于"callq"指令的实际文档.
我查看了http://support.amd.com/TechDocs/24594.pdf,这是"AMD64架构程序员手册第3卷:通用和系统指令",但它们只描述了CALL近距离和远距离指令.
我查看了gnu汇编程序https://sourceware.org/binutils/docs/as/index.html的文档,但找不到详细说明它支持的说明部分.
我理解它是对函数的调用,但我想知道细节.我在哪里可以找到它们?
我正在尝试从Linux amd64上的gdb中调查C/C++堆的状态,有一个很好的方法吗?
我尝试过的一种方法是"调用mallinfo()"但不幸的是我无法提取我想要的值,因为gdb没有正确处理返回值.
我不能轻易地编写一个函数来编译成我所连接的进程的二进制文件,所以我可以通过这种方式在我自己的代码中调用mallinfo()来实现我自己的函数来提取值.是否有一个聪明的技巧可以让我在飞行中做到这一点?
另一种选择可能是找到堆并遍历malloc头文件/空闲列表; 我非常感谢能够找到这些位置和布局的任何指示.
我一直在尝试谷歌并阅读约2个小时的问题,我已经学到了一些有趣的东西,但仍然找不到我需要的东西.
如何在AMD64架构的Linux汇编程序中使用RIP相对寻址?我正在寻找一个使用AMD64 RIP相对地址模式的简单示例(Hello world程序).
例如,以下64位汇编程序将与普通(绝对寻址)一起使用:
.text
.global _start
_start:
mov $0xd, %rdx
mov $msg, %rsi
pushq $0x1
pop %rax
mov %rax, %rdi
syscall
xor %rdi, %rdi
pushq $0x3c
pop %rax
syscall
.data
msg:
.ascii "Hello world!\n"
Run Code Online (Sandbox Code Playgroud)
我猜测使用RIP相对寻址的相同程序将是这样的:
.text
.global _start
_start:
mov $0xd, %rdx
mov msg(%rip), %rsi
pushq $0x1
pop %rax
mov %rax, %rdi
syscall
xor %rdi, %rdi
pushq $0x3c
pop %rax
syscall
msg:
.ascii "Hello world!\n"
Run Code Online (Sandbox Code Playgroud)
编译时,正常版本运行正常:
as -o hello.o hello.s && ld -s -o hello hello.o && ./hello
Run Code Online (Sandbox Code Playgroud)
但我无法使RIP版本正常工作. …
在最近的CPU上(至少在过去十年左右),除了各种可配置的性能计数器之外,英特尔还提供了三个固定功能硬件性能计数器.三个固定柜台是:
INST_RETIRED.ANY
CPU_CLK_UNHALTED.THREAD
CPU_CLK_UNHALTED.REF_TSC
Run Code Online (Sandbox Code Playgroud)
第一个计算退役指令,第二个计算实际周期,最后一个是我们感兴趣的."英特尔软件开发人员手册"第3卷的描述如下:
当核心未处于暂停状态而不处于TM停止时钟状态时,此事件计算TSC速率下的参考周期数.核心在运行HLT指令或MWAIT指令时进入暂停状态.此事件不受核心频率变化(例如,P状态)的影响,但计数与时间戳计数器的频率相同.当核心未处于暂停状态而不处于TM stopclock状态时,此事件可以估计经过的时间.
因此,对于CPU绑定循环,我希望该值与从中读取的自由运行TSC值相同rdstc,因为它们应该仅针对暂停的循环指令或"TM stopclock state"是什么发散.
我使用以下循环测试它(整个独立演示在github上可用):
for (int i = 0; i < 100; i++) {
PFC_CNT cnt[7] = {};
int64_t start = nanos();
PFCSTART(cnt);
int64_t tsc =__rdtsc();
busy_loop(CALIBRATION_LOOPS);
PFCEND(cnt);
int64_t tsc_delta = __rdtsc() - tsc;
int64_t nanos_delta = nanos() - start;
printf(CPU_W "d" REF_W ".2f" TSC_W ".2f" MHZ_W ".2f" RAT_W ".6f\n",
sched_getcpu(),
1000.0 * cnt[PFC_FIXEDCNT_CPU_CLK_REF_TSC] / nanos_delta,
1000.0 * tsc_delta / nanos_delta,
1000.0 * CALIBRATION_LOOPS / nanos_delta,
1.0 * cnt[PFC_FIXEDCNT_CPU_CLK_REF_TSC]/tsc_delta); …Run Code Online (Sandbox Code Playgroud)