Tag: 程序集

如何在不创建新进程的情况下运行汇编代码?

该文件包含本机程序集代码,我想在当前进程中运行它。 但我不想创建一个真实的文件(.com或.exe),所以我试过: … using namespace std; typedef void bitcode(); void testcode(){ cout<<"test"; }; int main() { bitcode *c=&testcode; // bitcode *c stands for the file containing the assembly code. bitcode *d=reinterpret_cast (malloc(20)); memcpy(d, c, 20); d(); // it doesn’t work return 0; }; 但是,当我调用d();它时它不起作用。 我想知道使用C / C ++执行此操作的正确方法是什么。 (我在Windows上,如果你能告诉我如何在Linux上制作它,我会非常感激) 非常感谢! PS:我不是要求“在没有创建新进程的情况下在另一个进程中运行可执行文件”。

为什么GCC使用Mov而不是推入函数调用?

所以我有这个C程序示例。 int worship(long john) { return 0 * john; } int main() { return worship(666); } 该程序集(基本上)看起来像这样: worship(long): pushq %rbp movq %rsp, %rbp movq %rdi, -8(%rbp) movl $0, %eax popq %rbp ret main: pushq %rbp movq %rsp, %rbp movl $666, %edi call worship(long) popq %rbp ret 我在阅读堆栈粉碎时遇到了这个问题。 在assemblyworship(long):它说movq %rdi, -8(%rbp)我希望它是基于我到目前为止阅读的所有内容使用pushq 。 这是GCC将参数推入堆栈的新方法吗?如果有的话,我可以使用编译器标志来切换它吗?

为什么明确的interrput标志导致C中的分段错误?

我正在学习关于Assembly和C.的一些基础知识用于学习目的我决定编写一个禁用Interrupts的简单程序,当用户想要在控制台中键入内容时他/她不能: #include int main(){ int a; printf(“enter your number : “); asm (“cli”); scanf(“%d”, &a); printf(“your number is %d\n” , a); return 0; } 但是当我用GCC编译它时,我得到了分段错误: Segmentation fault (core dumped) 当我用gdb调试它时,当程序到达asm(“cli”);时,我收到了这条消息asm(“cli”); 线: Program received signal SIGSEGV, Segmentation fault. main () at cli.c:6 6 asm (“cli”);

从C程序读取标志寄存器

为了好奇,我试图读取标志寄存器并以一种很好的方式将其打印出来。 我已经尝试使用gcc的asm关键字阅读它,但我无法让它工作。 任何提示怎么做? 我正在运行Intel Core 2 Duo和Mac OS X.以下代码就是我所拥有的。 我希望能告诉我是否发生溢出: #include int main (void){ int a=10, b=0, bold=0; printf(“%d\n”,b); while(1){ a++; __asm__ (“pushf\n\t” “movl 4(%%esp), %%eax\n\t” “movl %%eax , %0\n\t” :”=r”(b) : :”%eax” ); if(b!=bold){ printf(“register changed \n %d\t to\t %d”,bold , b); } bold = b; } } 这给出了分段错误。 当我运行gdb时,我得到了这个: Program received signal EXC_BAD_ACCESS, […]

未初始化的内存用于调试的常见值是什么?

很久以前我学会了用0xDEADBEEF填充未使用/未初始化的内存,以便在调试器或崩溃报告中,如果我看到该值,我知道我正在查看未初始化的内存。 我从崩溃报告中看到iOS使用0xBBADBEEF 。 人们使用了哪些其他创造性价值观? 任何特定的价值观都有任何特定的好处吗? 变成单词的价值最明显的好处是,至少在大多数人中,如果单词是用他们的语言,那么他们很容易突出,因为某些严格的数值不太可能突出。 但是,也许有其他理由选择数字? 例如,奇数可能会使处理器(68000)崩溃,例如在某些内存访问时崩溃,因此最好选择0x0BADBEEF超过0xBADBEEF0 。 他们的任何其他值(可能是处理器特定的)是否具有使用未初始化内存的具体好处?

C中的无符号溢出

考虑以下C代码: #include uint32_t inc(uint16_t x) { return x+1; } 当使用gcc-4.4.3在纯x86_64系统上使用标志-std = c99 -march = core2 -msse4.1 -O2 -pipe -Wall进行编译时,它会生成 movzwl %di,%eax inc %eax retq 现在,在C中预测无符号溢出。我不太了解x86_64汇编,但据我所知,16位参数寄存器被移动到32位寄存器,该寄存器递增并返回。 我的问题是,如果x == UINT16_MAX怎么办。 会发生溢出,标准规定x + 1 == 0,对吗? 但是,如果%eax是一个32位寄存器,它现在包含UINT16_MAX + 1,这是不正确的。 这让我在这里连接一个问题:是否有一种可移植的方法来禁用C中的无符号溢出,这样编译器就可以假设存储在大寄存器中的小变量的高位始终为0(所以它不需要清除它们)? 如果不是(或者如果解决方案在语法上是令人讨厌的),至少在GCC中有没有办法做到这一点? 非常感谢您的宝贵时间。

我正在编写自己的JIT解释器。 如何执行生成的指令?

我打算编写自己的JIT解释器作为VM课程的一部分。 我对高级语言,编译器和解释器有很多了解,但很少或根本没有关于x86汇编(或C)的知识。 实际上我不知道JIT是如何工作的,但这是我对它的看法:用一些中间语言读入程序。 将其编译为x86指令。 确保最后一条指令返回到VM代码中的某个地方。 将指令存储在内存中的某些位置。 无条件跳转到第一条指令。 瞧! 所以,考虑到这一点,我有以下小C程序: #include #include #include int main() { int *m = malloc(sizeof(int)); *m = 0x90; // NOP instruction code asm(“jmp *%0” : /* outputs: */ /* none */ : /* inputs: */ “d” (m) : /* clobbers: */ “eax”); return 42; } 好的,所以我的目的是让这个程序将NOP指令存储在内存中的某个位置,跳转到该位置然后可能崩溃(因为我没有设置任何方式让程序返回到main)。 问题:我是走在正确的道路上吗? 问题:你能告诉我一个经过修改的程序,它可以找到回到main中某个地方的方法吗? 问题:我应该注意的其他问题? PS:我的目标是获得理解,而不是以正确的方式做所有事情。 感谢所有的反馈。 […]

如何在位图中的位之间插入零?

我有一些性能很重的代码执行位操作。 它可以简化为以下明确定义的问题: 给定一个13位位图,构造一个26位位图,其中包含在偶数位置间隔的原始位 。 为了显示: 0000000000000000000abcdefghijklm (input, 32 bits) 0000000a0b0c0d0e0f0g0h0i0j0k0l0m (output, 32 bits) 我目前在C中以下列方式实现它: if (input & (1 << 12)) output |= 1 << 24; if (input & (1 << 11)) output |= 1 << 22; if (input & (1 << 10)) output |= 1 << 20; … 我的编译器(MS Visual Studio)将其转换为以下内容: test eax,1000h jne 0064F5EC […]

在C中获取帧指针

我试图在我的C程序中获得FP,我尝试了两种不同的方式,但它们都与我运行GDB时的方式不同。 我尝试的第一种方法,我在C中为Assembly函数创建了一个协议函数: int* getEbp(); 我的代码看起来像这样: int* ebp = getEbp(); printf(“ebp: %08x\n”, ebp); // value i get here is 0xbfe2db58 while( esp <= ebp ) esp -= 4; printf( "ebp: %08x, esp" ); //value i get here is 0xbfe2daec 我的汇编代码 getEbp: movl %ebp, %eax ret 我尝试使原型函数只返回一个int,但这也与我的GDB输出不匹配。 我们正在使用x86程序集。 编辑:拼写错误,我的getEsp函数看起来与另一个完全相同: getEsp: movl %esp, %eax ret

无法识别的仿真模式:MinGW32上的elf_i386

我正在尝试创建一个内核,我无法将C输出与程序集链接起来。 ld 。 我收到了错误: 无法识别的仿真模式:elf_i386 我正在使用Windows 10专业版与MinGW32和MSYS。 我正在使用的代码: link.ld /* * link.ld */ OUTPUT_FORMAT(elf32-i386) ENTRY(start) SECTIONS { . = 0x100000; .text : { *(.text) } .data : { *(.data) } .bss : { *(.bss) } } kernel.c /* * kernel.c */ void kmain(void) { const char *str = “my first kernel”; char *vidptr = (char*)0xb8000; […]