Tag: x86 64

x86_64调用约定和堆栈帧

我试图理解GCC(4.4.3)为在Ubuntu Linux下运行的x86_64机器生成的可执行代码。 特别是,我不明白代码如何跟踪堆栈帧。 在过去,在32位代码中,我习惯于在几乎所有function中看到这个“序幕”: push %ebp movl %esp, %ebp 然后,在function结束时,也会出现“结局” sub $xx, %esp # Where xx is a number based on GCC’s accounting. pop %ebp ret 或简单地说 leave ret 这完成了同样的事情: 将堆栈指针设置为当前帧的顶部,就在返回地址的正下方 恢复旧的帧指针值。 在64位代码中,正如我通过objdump反汇编看到的那样,许多函数不遵循这个约定 – 它们不会推送%rbp然后将%rsp保存到%rbp,像GDB这样的调试器如何构建回溯? 我真正的目标是尝试找出一个合理的地址,当执行到达程序中的任意函数的开始时,可​​以将堆栈指针向下移动时,将其视为用户堆栈的顶部(最高地址)。 例如,对于“top”,argv的原始地址是理想的 – 但我无法从主要调用的任意函数访问它。 我起初以为我可以使用旧的回溯方法:追踪保存的帧指针值,直到保存的值为0 – 然后,下一个可以算作最高实际值。 (这与获取argv的地址不同,但它会 – 比如说,找出_start或任何_start调用的堆栈指针值[例如__libc_start_main]。)现在,我不知道如何获取64位代码中的等效地址。 谢谢。

x86_64对齐堆栈并在不保存寄存器的情况下恢复

我正在为x86_64编写中断处理例程。 ABI指定在调用C函数之前,我必须将堆栈对齐到16个字节。 x86_64 ISA指定在进入ISR时,我的堆栈是8字节对齐的。 我需要将我的堆栈指针对齐到16个字节。 问题是从我的C函数返回时,我必须恢复(可能)未对齐的堆栈指针,以便我可以正确地从我的中断返回。 我想知道是否有办法在不使用通用寄存器的情况下执行此操作?

如何获取c代码来执行hex字节码?

我想要一个简单的C方法,能够在Linux 64位机器上运行hex字节码。 这是我的C程序: char code[] = “\x48\x31\xc0”; #include int main(int argc, char **argv) { int (*func) (); func = (int (*)()) code; (int)(*func)(); printf(“%s\n”,”DONE”); } 我试图运行的代码( “\x48\x31\xc0” )我通过”\x48\x31\xc0″这个简单的汇编程序获得(它不应该真的做任何事情) .text .globl _start _start: xorq %rax, %rax 然后编译并objdump它以获取字节码。 但是,当我运行我的C程序时,我得到一个分段错误。 有任何想法吗?

Bounds检查64位硬件

我正在hacks.mozilla.org上阅读64位Firefox版本的博客 。 作者说: 对于asm.js代码,增加的地址空间还允许我们使用硬件内存保护来安全地从asm.js堆访问中删除边界检查。 收益非常显着: asmjs-apps上的8%-17% – * –在arewefastyet.com上报告的吞吐量测试。 我试图了解64位硬件如何对C / C ++进行自动边界检查(假设编译器支持硬件)。 我在SO中找不到任何答案。 我找到了一篇关于这个主题的技术论文 ,但我无法理解这是如何完成的。 有人可以在边界检查中解释64位硬件辅助吗?

SSE指令在哪里优于正常指令

x86-64的SSE指令(向量指令)在哪里优于正常指令。 因为我所看到的是,执行SSE指令所需的频繁加载和存储会使由于向量计算而获得的任何增益无效。 那么有人可以给我一个示例SSE代码,它比普通代码表现更好。 它可能是因为我分别传递每个参数,像这样… __m128i a = _mm_set_epi32(pa[0], pa[1], pa[2], pa[3]); __m128i b = _mm_set_epi32(pb[0], pb[1], pb[2], pb[3]); __m128i res = _mm_add_epi32(a, b); for( i = 0; i < 4; i++ ) po[i] = res.m128i_i32[i]; 有没有办法我可以一次性传递所有4个整数,我的意思是一次性传递整个128字节的pa ? 并res.m128i_i32将res.m128i_i32分配给po ?

如何使用CMAKE从命令行在Windows上构建x86和/或x64?

使用Visual Studio让cmake在Windows上构建x86的一种方法是这样的: 启动x86的Visual Studio命令提示符 运行cmake: cmake -G “NMake Makefiles” \path_to_source\ NMAKE 使用Visual Studio让cmake在Windows上构建x64的一种方法是这样的: 启动x64的Visual Studio命令提示符 运行cmake: cmake -G “NMake Makefiles” \path_to_source\ NMAKE 使用Cmake,我如何编译其中一个或两个架构? (就像Visual Studio在IDE中的表现一样)

x86-64分段故障保存堆栈指针

我目前正在关注本教程 ,但我不是该学校的学生。 GDB thread_start上的thread_start给出了一个分段错误: movq %rsp, (%rdi) # save sp in old thread’s tcb 这是我回溯时的附加信息: #0 thread_start () at thread_start.s:16 #1 0x0000000180219e83 in _cygtls::remove(unsigned int)::__PRETTY_FUNCTION__ () from /usr/bin/cygwin1.dll #2 0x00000000ffffcc6b in ?? () Backtrace stopped: previous frame inner to this frame (corrupt stack?) 作为一个新手,我不能为我的生活找出原因。 这是我的主要文件: #define STACK_SIZE 1024*1024 //Thread TCB struct thread { unsigned char […]

为什么在这个函数序言中没有“sub rsp”指令,为什么函数参数存储在负rbp偏移量?

这就是我通过阅读一些内存分段文档所理解的:当一个函数被调用时,有一些指令(称为函数序言)将帧指针保存在堆栈上,将堆栈指针的值复制到基指针中并保存一些局部变量的内存。 这是我尝试使用GDB调试的一个简单代码: void test_function(int a, int b, int c, int d) { int flag; char buffer[10]; flag = 31337; buffer[0] = ‘A’; } int main() { test_function(1, 2, 3, 4); } 调试此代码的目的是了解调用函数时堆栈中发生的情况:因此我必须在执行程序的各个步骤(在调用函数之前和执行期间)检查内存。 虽然我通过检查基指针设法看到返回地址和保存的帧指针之类的东西,但我真的无法理解在反汇编代码之后我要写的内容。 拆解: (gdb) disassemble main Dump of assembler code for function main: 0x0000000000400509 : push rbp 0x000000000040050a : mov rbp,rsp 0x000000000040050d : mov […]

在C和C ++中调用函数时EAX寄存器初始化的差异

当编译为C程序或C ++程序(对于Linux x86-64)时,小程序的程序集之间存在奇怪的差异。 有问题的代码: int fun(); int main(){ return fun(); } 将其编译为C程序(使用gcc -O2 )可以得到: main: xorl %eax, %eax jmp fun 但是将其编译为C ++程序(使用g++ -02 )会产生: main: jmp _Z3funv 我觉得很困惑,C版本用0 ( xorl %eax, %eax )初始化主函数的返回值。 C语言的哪个特性对这种必要性负责? 编辑:对于int fun(void);来说确实如此int fun(void); 没有初始化eax寄存器。 如果根本没有fun原型,即: int main(){ return fun(); } 然后C编译器再次将eax寄存器归零。

如何告诉gcc在struct中禁用填充?

我不确定它是否正常或者它是编译器错误但是我有一个包含很多成员的C结构。 其中包括: struct list { … … const unsigned char nop=0x90; // 27 bytes since the begining of the structure const unsigned char jump=0xeb; // 28 bytes since the begining of the structure const unsigned char hlt=0xf4; // 29 bytes since the begining of the structure unsigned __int128 i=0xeb90eb90eb90eb90f4f4 // should start at the 30th […]