Tag: 汇编

C编程:从汇编程序的角度来看++ i和i = i + 1之间的区别?

这是一个面试问题。 我说他们是一样的,但这被判定为不正确的回应。 从汇编程序的角度来看,有什么可以想象的区别吗? 我使用默认的gcc优化和-S编译了两个简短的C程序来查看汇编器输出,它们是相同的。

如何在现代使用汇编(例如使用C / C ++)?

我理解计算机如何处理基本原理,例如,程序可以用C#,C等“高级”语言编写,然后将其分解为目标代码,然后分解为处理器理解的二进制代码。 但是,我真的想学习assembly,以及它如何在现代应用中使用。 我知道处理器在基本x86指令集之上有不同的指令集。 所有汇编语言都支持所有指令集吗? 有多少汇编语言? 有多少与其他语言一起使用? 如何在程序集中编写例程,然后将其编译为对象/二进制代码? 那么有人会如何用C或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页

将c代码转换为x86程序集的简便方法?

是否有一种简单的方法(如免费程序)可以将c / c ++代码转换为x86程序集? 我知道任何c编译器都做了非常类似的事情,我可以编译c代码,然后反汇编编译的可执行文件,但这有点过分,我想要的只是转换几行代码。 有谁知道一些程序可以做到这一点? 编辑:我知道GCC编译器这样做,但它是AT&T语法,我正在寻找英特尔语法(不确定它是否称为英特尔语法)。 AT&T语法看起来有点像胡言乱语,有些命令以相反的顺序使用操作数,而不是我习惯的方式,它可能会让人感到困惑。

有人可以解释malloc的含义(20 * c | – (20 *(unsigned __int64)(unsigned int)c >> 32!= 0))

在IDA生成的反编译代码中,我看到如下表达式: malloc(20 * c | -(20 * (unsigned __int64)(unsigned int)c >> 32 != 0)) malloc(6 * n | -(3 * (unsigned __int64)(unsigned int)(2 * n) >> 32 != 0)) 有人可以解释这些计算的目的吗? c和n是int(有符号整数)值。 更新。 原始C ++代码是使用MSVC为32位平台编译的。 这是上面第二行反编译C代码的汇编代码(malloc(6 * ..)): mov ecx, [ebp+pThis] mov [ecx+4], eax mov eax, [ebp+pThis] mov eax, [eax] shl eax, 1 xor ecx, ecx […]

从C调用的Intel 8086汇编程序

我需要为汇编语言开发一个过程,并从C语言调用该过程(传递一个字符串并返回一个整数值)。 我的assembly程序很好“独立”。 我需要帮助将它们连接在一起。 程序应该在Intel 8086上运行。我需要使用MASM或emu8086作为汇编程序/模拟器。 请推荐一个C编译器,以及制作能够调用汇编过程并获取返回值的简单C程序的方法。 如何将字符串传递给此外部函数? 如何连接ASM文件和C文件? (编译器如何知道此过程的定义/代码在哪里?) 如何从汇编语言中获取从C发送的字符串,以及如何将整数返回到C?

如何将库定义的符号加载到指定的位置?

测试在Ubuntu 12.04,32位, gcc 4.6.3。 基本上我正在对ELF二进制文件进行一些二进制操作工作,我现在要做的是组装一个汇编程序并保证libc符号被我加载到预定义的地址。 让我在一个简单的例子中详细说明。 假设在原始代码中使用了libc符号stdout@GLIBC_2.0 。 #include int main() { FILE* fout = stdout; fprintf( fout, “hello\n” ); } 当我编译它并使用以下命令检查符号地址时: gcc main.c readelf -s a.out | grep stdout 我懂了: 0804a020 4 OBJECT GLOBAL DEFAULT 25 stdout@GLIBC_2.0 (2) 0804a020 4 OBJECT GLOBAL DEFAULT 25 stdout@@GLIBC_2.0 和.bss部分是这样的: readelf -S a.out | grep bss [25] .bss […]

运行libsandbox

我目前正在开发一个在线C / C ++ /汇编编译器,我偶然发现了一个名为libsandbox的软件。 这使我能够运行在线编写的代码,编译它并拦截系统调用。 首先,我是Linux环境中的新手。 我已下载tar.gz,解压缩,配置并安装它。 这没有任何错误,但现在我很难运行它。 我该如何在这个沙箱中运行C / C ++程序? 我必须提供.c / .cpp文件吗? 编译后的可执行文件? 这可能是一个非常愚蠢的问题。 我在互联网上搜索了如何做,并阅读了自述文件,但他们没有给我一个线索。 提前致谢!

为什么在这个函数序言中没有“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 […]

切换特定位

所以我已经看到了诸如在ith positon稍微切换一下的问题以及如何设置,清除和切换一个位? ,但我想知道是否有一个很好的方法在x86-64汇编中切换第i个位置? 我尝试用C语言编写并查看程序集,并不完全明白为什么有些东西存在。 C: unsigned long toggle(unsigned long num, unsigned long bit) { num ^= 1 << bit; return num; } int main() { printf("%ld\n", toggle(100, 60)); return 0; } 从GDB切换function组件: push rbp mov rbp, rsp mov QWORD PTR [rbp-0x8],rdi mov QWORD PTR [rbp-0x10],rsi mov rax, QWORD PTR [rbp-0x10] mov edx, 0x1 mov ecx, […]