Tag: x86

c库x86 / x64汇编程序

是否有用于将x86 / x64汇编字符串组装到操作码的C库? 示例代码: /* size_t assemble(char *string, int asm_flavor, char *out, size_t max_size); */ unsigned char bytes[32]; size_t size = assemble(“xor eax, eax\n” “inc eax\n” “ret”, asm_x64, &bytes, 32); for(int i = 0; i < size; i++) { printf("%02x ", bytes[i]); } /* Output: 31 C0 40 C3 */ 我看过asmpure ,但它需要修改才能在非Windows机器上运行。 我实际上都需要一个汇编器和一个反汇编器,是否有一个提供两者的库?

如何获取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程序时,我得到一个分段错误。 有任何想法吗?

RDTSCP与RDTSC + CPUID

我正在做一些Linux内核时序,特别是在中断处理路径中。 我一直在使用RDTSC进行计时,但是我最近了解到它并不一定准确,因为指令可能无序发生。 然后我尝试了: RDTSC + CPUID(在这里以相反的顺序)刷新管道,由于超级调用和诸如此类的原因,在虚拟机(我的工作环境)上产生高达60倍的开销(!) 。 无论是否启用了HW Virtualization,都可以使用此function。 最近我遇到了RDTSCP *指令,它看起来像RDTSC + CPUID那样做,但更高效,因为它是一个较新的指令 – 相对而言只有1.5x-2x的开销。 我的问题: RDTSCP作为测量点真的准确吗 ,它是做出时间的“正确”方法吗? 另外要明确一点,我的时间基本上就是这样,内部: 保存当前循环计数器值 执行一种基准测试(即:磁盘,网络) 将当前和上一个周期计数器的增量添加到累加器值,并按单个中断递增计数器 最后,将delta / accumulator除以中断次数,得到每次中断的平均周期成本。 * http://www.intel.de/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf第27页

乱序执行和记忆围栏

我知道现代CPU可以无序执行,但是他们总是按顺序退出结果,如维基百科所述。 “Out of Oder处理器及时填写这些”插槽“和其他准备就绪的指令, 然后在结束时重新排序结果,使其看起来正常处理指令。 ” 现在,在使用多核平台时,据说需要内存栅栏,因为由于乱序执行,可以在此处打印错误的x值。 Processor #1: while f == 0 ; print x; // x might not be 42 here Processor #2: x = 42; // Memory fence required here f = 1 现在我的问题是,由于乱序处理器(我假设MultiCore处理器的情况下的核心)总是按顺序退出结果,那么内存栅栏的必要性是什么。 难道多核处理器的核心不会看到仅从其他核心退役的结果,或者它们是否也会看到正在进行中的结果? 我的意思是在我上面给出的例子中,当处理器2最终将结果退出时, x的结果应该在f之前,对吧? 我知道在乱序执行期间它可能在x之前修改了f但是它必须在x之前没有退出它,对吗? 现在有了按顺序退出结果和缓存一致性机制,为什么你需要在x86中使用内存栅栏?

在不使用gcc的内联汇编的情况下访问寄存器

我想在不编写内联汇编的情况下读取堆栈指针寄存器值。我想这样做的原因是因为我想将堆栈指针寄存器值分配给数组元素,我发现使用内联汇编访问数组很麻烦。 所以我想做那样的事情。 register “rsp” long rsp_alias; <— How do I achieve something like that in gcc? long current_rsp_value[NUM_OF_THREADS]; current_rsp_value[tid] = rsp_alias; gcc有什么可能吗?

今天和20年前的记忆对齐

在着名的论文“Smashing the Stack for Fun and Profit”中,它的作者采用了C函数 void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; } 并生成相应的汇编代码输出 pushl %ebp movl %esp,%ebp subl $20,%esp 作者解释说,由于计算机以字大小的倍数寻址存储器,编译器在堆栈上保留20个字节(缓冲区1为8个字节,缓冲区2为12个字节)。 我试图重新创建这个例子并获得以下内容 pushl %ebp movl %esp, %ebp subl $16, %esp 不同的结果! 我尝试了缓冲区1和缓冲区2的各种大小组合,似乎现代的gcc不再将缓冲区大小填充到字大小的倍数。 相反,它遵循-mpreferred-stack-boundary选项。 作为一个例子 – 使用纸张的算术规则,对于buffer1 [5]和buffer2 [13],我会在堆栈上保留8 + 16 = 24个字节。 但实际上我有32个字节。 这篇论文很古老,自那以后发生了很多事情。 我想知道,究竟是什么推动了这种行为的改变? 这是向64位机器的转变吗? 或者是其他东西? 编辑 […]

检查Visual Studio C ++编译器生成的代码,第1部分

可能重复: 为什么发出这样复杂的代码来将有符号整数除以2的幂? 背景 我只是通过检查编译器生成的二进制代码来学习x86 asm。 在Visual Studio 2010 beta 2中使用C ++编译器编译的代码。 Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.21003.01 for 80×86 C代码(sandbox.c) int mainCRTStartup() { int x=5;int y=1024; while(x) { x–; y/=2; } return x+y; } 使用Visual Studio命令提示符编译它 cl /c /O2 /Oy- /MD sandbox.c link /NODEFAULTLIB /MANIFEST:NO /SUBSYSTEM:CONSOLE sandbox.obj 在OllyDgb中解雇sandbox.exe 以下从入口点开始。 00401000 >/$ B9 05000000 […]

x86调用约定:堆栈传递的参数应该是只读的吗?

似乎最先进的编译器将堆栈传递的参数视为只读。 请注意,在x86调用约定中,调用者将参数压入堆栈,并且被调用者使用堆栈中的参数。 例如,以下C代码: extern int goo(int *x); int foo(int x, int y) { goo(&x); return x; } 由OS X 10.10中的clang -O3 -c gc -S -m32编译成: .section __TEXT,__text,regular,pure_instructions .macosx_version_min 10, 10 .globl _foo .align 4, 0x90 _foo: ## @foo ## BB#0: pushl %ebp movl %esp, %ebp subl $8, %esp movl 8(%ebp), %eax movl %eax, -4(%ebp) leal […]

为什么返回浮点值会改变其值?

以下代码在Red Hat 5.4 32位上引发了assert ,但在Red Hat 5.4 64位(或CentOS)上运行。 在32位上,我必须将millis2seconds的返回值放在一个变量中,否则会引发assert ,表明函数返回的double值与传递给它的值不同。 如果你评论“#define BUG”行,它就可以了。 感谢@R,将-msse2 -mfpmath选项传递给编译器,使得millis2seconds函数的两个变量都能正常工作。 /* * TestDouble.cpp */ #include #include #include static double millis2seconds(int millis) { #define BUG #ifdef BUG // following is not working on 32 bits architectures for any values of millis // on 64 bits architecture, it works return (double)(millis) / 1000.0; […]

_malloc在assembly中到底做了什么?

public main main proc near push ebp mov ebp, esp and esp, 0FFFFFFF0h sub esp, 30h mov dword ptr [esp], 8 ; size call _malloc mov [esp+2Ch], eax mov dword ptr [esp+4], 4 mov eax, [esp+2Ch] mov [esp], eax call __start 上面的代码代表了我正在处理的大型项目的一部分。 我试图将此代码转换为C等效,但我很难理解malloc的工作原理。 我估计8个字节将是被分配的内存的大小; 但是,我不确定这条线。 mov eax, [esp+2ch] malloc对eax做了什么? 那么这是等效的C代码吗? int main(void) { int *ptr1; […]