Tag: 程序集

function到mangle / demangle函数

我之前已经certificate,C ++函数不易在汇编中表示。 现在我有兴趣阅读这种或那种方式,因为callgrind,valgrind的一部分,显示它们在组装时被解构,它们被显示为损坏,所以我想要破坏valgrind函数输出或者取消函数的汇编名称。 有人试过这样的东西吗? 我正在查看一个网站 ,发现以下内容: Code to implement demangling is part of the GNU Binutils package; see libiberty/cplus-dem.c and include/demangle.h. 有人试过这样的东西,我想在C中解码/破坏吗? 我的编译器是gcc 4.x.

在32位计算机上实现64位运算

以下代码计算x和y的乘积,并将结果存储在内存中。 数据类型ll_t被定义为等于long long。 typedef long long ll_t; void store_prod(ll_t *dest, int x, ll_t y) { *dest = x*y; } gcc生成以下汇编代码来实现计算:dest at%ebp + 8,x at%ebp + 12,y at%ebp + 16 1 movl 16(%ebp), %esi 2 movl 12(%ebp), %eax 3 movl %eax, %edx 4 sarl $31, %edx 5 movl 20(%ebp), %ecx 6 imull %eax, %ecx 7 movl […]

gcc内联汇编错误“mov的操作数类型不匹配”

//quick inline asm statements performing the swap_byte for key_scheduling inline void swap_byte(unsigned char *x, unsigned char *y) { unsigned char t; asm(“movl %1, %%eax;” “movl %%eax, %0;” :”=r”(t) :”r”(*x) :”%eax”); asm(“movl %1, %%eax;” “movl %%eax, %0;” :”=r”(*x) :”r”(*y) :”%eax”); asm(“movl %1, %%eax;” “movl %%eax, %0;” :”=r”(*y) :”r”(t) :”%eax”); } 在这里,我试图从x交换char并存储在y ,并且y与x交换相同。 我已经通过将movl更改为mov来编译这些指令,但没有成功。 编译/链接的问题在哪里? 以下是cygwin中编译的输出: $ […]

任何人都可以帮我解释WinDbg中这个简单的反汇编吗?

我得到了以下简单的C ++代码: #include int main(void) { ::printf(“\nHello,debugger!\n”); } 从WinDbg,我得到了以下反汇编代码: SimpleDemo!main: 01111380 55 push ebp 01111381 8bec mov ebp,esp 01111383 81ecc0000000 sub esp,0C0h 01111389 53 push ebx 0111138a 56 push esi 0111138b 57 push edi 0111138c 8dbd40ffffff lea edi,[ebp-0C0h] 01111392 b930000000 mov ecx,30h 01111397 b8cccccccc mov eax,0CCCCCCCCh 0111139c f3ab rep stos dword ptr es:[edi] 0111139e 8bf4 […]

Linux / gcc中InterlockedIncrement的等价物

这将是一个非常简单的问题(可能重复),但我无法找到它。 Win32 API提供了一组非常方便的primefaces操作(如内在函数),例如InterlockedIncrement ,它发出lock add x86代码。 此外, InterlockedCompareExchange映射到lock cmpxchg 。 但是,我想在Linux中用gcc做到这一点。 由于我正在使用64位,因此无法使用内联汇编。 是否存在gcc的内在函数?

BITWISE AND操作如何在C程序中占用比ARITHMETIC ADDITION操作更多的CPU时钟?

我想测试按位运算是否真的比算术运算更快。 我以为他们是。 我写了一个小的C程序来测试这个假设,令我惊讶的是,加法平均比按位AND运算少。 这对我来说是令人惊讶的,我无法理解为什么会这样。 根据我所知的附加,来自较低有效位的进位应该被携带到下一位,因为结果也取决于进位。 对我来说,逻辑运算符比加法更慢是没有意义的。 我的鳕鱼在下面: #include #include int main() { int x=10; int y=25; int z=x+y; printf(“Sum of x+y = %i”, z); time_t start = clock(); for(int i=0;i<100000;i++)z=x+y; time_t stop = clock(); printf("\n\nArithmetic instructions take: %d",stop-start); start = clock(); for(int i=0;i<100000;i++)z=x&y; stop = clock(); printf("\n\nLogic instructions take: %d",stop-start); } 一些结果: Arithmetic instructions take: […]

如何在16位模式下使用GDB?

我有以下代码,我试图实现一个使用BIOS函数打印字符串的函数: int printString(char* string) { int i = 0; while (*(string + i) != ‘\0’) { char al = *(string + i); char ah = 0xe; int ax = ah * 256 + al; interrupt(0x10,ax,0,0,0); i++; } return i; } 函数中断在汇编中实现。 它调用适当的BIOS中断,如第一个参数所给出的,其余参数分别包含ax,bx,cx和dx寄存器的内容: .global _interrupt _interrupt: push bp mov bp, sp push si push ds mov […]

如何在Assembly Langauge X86中检测溢出条件

我有一个任务,我们必须编写两个函数。 还必须使用处理器的条件代码检测溢出条件,并返回0以指示已遇到错误。 我能够写出这些function。 .file “formula.c” .text .globl _nCr .def _nCr; .scl 2; .type 32; .endef _nCr: pushl %ebp movl %esp, %ebp subl $56, %esp movl 8(%ebp), %eax movl %eax, (%esp) testl %eax, %eax call _factorial movl %eax, -12(%ebp) movl 12(%ebp), %eax addl $1, %eax movl %eax, (%esp) call _factorial movl %eax, -16(%ebp) movl 12(%ebp), %eax […]

初始化变量并在声明后立即赋值给它是否有区别?

假设一个纯粹的非优化编译器,在初始化变量并在声明后为其赋值时,机器代码是否存在差异? 初始化方法 : int x = 2; 作业方式 : int x; x = 2; 我使用GCC输出为这两种不同方法生成的程序集,并且两者都产生了一条机器指令: movl $2, 12(%esp) 该指令只是将x变量保存的内存设置为值2 。 GCC可能正在优化这一点,因为它可以识别操作的最终结果; 但我认为这是解释这两个版本的唯一方法。 我的理由是两个版本都做同样的事情:将内存的一部分设置为特定值。 那么,如果生成的机器代码相同,那么为什么通常会在术语“ 初始化 ”和“ 赋值 ”之间进行区分? 术语“ 初始化 ”是否纯粹用于区分具有特定值的变量,这些变量具有在内存中留下任何垃圾值的那些(非初始化)变量?

何时在扩展GCC内联汇编中使用earlyclobber约束?

我知道何时使用补鞋匠列表(例如列出在程序集中修改的寄存器,以便它不被选择用作输入寄存器等),但我无法绕过早期约束条件& 。 如果列出输出,那是否已经意味着输入不能使用所选寄存器(除了匹配数字约束)? 例如: asm( “movl $1, %0;” “addl $3, %0;” “addl $4, %1;” “addl %1, %0;” : “=g”(num_out) : “g”(num_in) : ); 输出变量会不会甚至需要? 编译器应该知道为输出选择的寄存器,因此知道不要将它用于输入。