Tag: 程序集

是否可以在Linux上没有链接libc的情况下将C转换为asm?

测试平台在Linux 32位上。 (但也欢迎Windows 32位上的某些解决方案) 这是交响代码段: int a = 0; printf(“%d\n”, a); 如果我使用gcc生成汇编代码 gcc -S test.c 然后我会得到: movl $0, 28(%esp) movl 28(%esp), %eax movl %eax, 4(%esp) movl $.LC0, (%esp) call printf leave ret 而这个汇编代码需要链接到libc才能工作(因为调用printf) 我的问题是: 是否可以将C转换为asm,只使用显式使用系统调用 ,而不使用libc? 像这样: pop ecx add ecx,host_msg-host_reloc mov eax,4 mov ebx,1 mov edx,host_msg_len int 80h mov eax,1 xor ebx,ebx int 80h […]

如何按指令读取二进制可执行文件?

有没有办法以编程方式从x86架构上的二进制可执行文件中读取给定数量的指令? 如果我有一个简单的C程序hello.c的二进制文件: #include int main(){ printf(“Hello world\n”); return 0; } 在使用gcc编译之后,反汇编函数main如下所示: 000000000000063a : 63a: 55 push %rbp 63b: 48 89 e5 mov %rsp,%rbp 63e: 48 8d 3d 9f 00 00 00 lea 0x9f(%rip),%rdi # 6e4 645: e8 c6 fe ff ff callq 510 64a: b8 00 00 00 00 mov $0x0,%eax 64f: 5d pop %rbp […]

使用SIGILL与CPU探测进行AVXfunction检测

我正在尝试确定一种检测英特尔和AMD处理器上AVX和AVX2可用性的有效方法。 在阅读英特尔软件开发人员手册第一卷( 使用XSAVEfunction集管理状态 ,第310页)时,我更加惊讶地发现它更接近SSE和XSAVE。 英特尔发布了一些用于在启用Is AVX时检测AVX可用性的代码? 代码如下所示,并不太痛苦。 问题是,Visual Studio是一个痛点,因为我们需要将代码从C / C ++文件中移出到X64的ASM文件中。 其他人似乎采用SIGILL方法来检测AVX可用性。 或者他们无意中使用了SIGILL方法。 例如,请参阅AVX指令上的SIGILL 。 我的问题是,使用SIGILL方法检测AVX可用性是否安全? 这里, “安全”表示当CPU和OS支持AVX时,AVX指令不会生成SIGILL ; 否则它会生成一个SIGILL 。 下面的代码适用于32位计算机,它来自英特尔博客是否已启用AVX? 令我担心的是操纵控制寄存器。 读取和写入某些X86和ARM控制寄存器有时需要超级用户/管理员权限。 这是我更喜欢SIGILL (并避免控制寄存器)的原因。 ; int isAvxSupported(); isAvxSupported proc xor eax, eax cpuid cmp eax, 1 ; does CPUID support eax = 1? jb not_supported mov eax, 1 cpuid and ecx, 018000000h […]

矢量化的strlen逃脱阅读未分配的内存

在研究OSX 10.9.4的strlen实现时,我注意到它总是比较一个16字节的块并向前跳过到后面的16个字节,直到它遇到’\0 ‘。 相关部分: 3de0: 48 83 c7 10 add $0x10,%rdi 3de4: 66 0f ef c0 pxor %xmm0,%xmm0 3de8: 66 0f 74 07 pcmpeqb (%rdi),%xmm0 3dec: 66 0f d7 f0 pmovmskb %xmm0,%esi 3df0: 85 f6 test %esi,%esi 3df2: 74 ec je 3de0 0x10是hex的16字节。 当我看到它时,我想知道:这个记忆也可以不被分配。 如果我分配了一个20字节的C字符串并将其传递给strlen ,它将读取36字节的内存。 为什么允许这样做? 我开始寻找并发现访问数组越界有多危险? 例如,确认它绝对不是一件好事,未分配的内存可能未被映射。 然而,必须有一些东西使这项工作。 我的一些假设: OSX不仅保证其分配是16字节对齐的,而且还保证分配的“量子”是16字节的块。 换句话说,分配5个字节实际上将分配16个字节。 分配20个字节实际上将分配32个字节。 当你编写asm时读取数组的结尾本身并没有坏处,因为它不是未定义的行为,只要它在界限内(在页面内?)。 […]

是否有任何此类处理器具有绕过缓存的指令?

是否有任何此类处理器具有绕过特定数据的缓存的指令? 这个问题也有一个答案,表明SSE4.2指令绕过缓存。 有人可以启发我吗?

assembly中纯粹的高位乘法?

要实现0到1之间的实数,通常使用ANSI浮点数或双精度数。 但是0到1之间的固定精度数(模数为1的小数)可以有效地实现为32位整数或16位字,它们会像正常的整数/字一样添加,但会增加“错误的方式”,这意味着当你乘以X倍时是的,你保留了产品的高位。 这相当于乘以0.X和0.Y,其中X的所有位都在小数点后面。 同样,-1和1之间的带符号数也可以通过一个额外位和一个移位来实现。 如何在C中实现固定精度mod 1或mod 2(特别是使用MMX或SSE)? 我认为这种表示对于酉矩阵的有效表示非常有用,对于数值密集的物理模拟。 它使更多MMX / SSE具有整数量,但您需要更高级别的PMULHW访问权限。

为什么GCC没有优化对printf的这个调用?

#include int main(void) { int i; scanf(“%d”, &i); if(i != 30) { return(0); } printf(“i is equal to %d\n”, i); } 结果字符串似乎总是“我等于30”,那么,为什么GCC不会通过调用puts()或write()来优化对printf的调用? (刚刚使用gcc -O3 (版本5.3.1)或Godbolt Compiler Explorer检查生成的程序集)

从C控制台app调用的CRC32汇编程序函数

我试图在C代码中从外部文件调用asm函数。 它建立得很好,但结果并不像它应该的那样。 我没有看到文件校验和,而是看到一些奇怪的字符。 #include #include #include extern “C” unsigned long __stdcall CRC32(size_t sizeOfFile, char buffer[]); int fsize(char* file) { int size; FILE* fh; fopen_s(&fh, file, “rb” ); if(fh != NULL){ if( fseek(fh, 0, SEEK_END) ){ fclose(fh); return -1; } size = ftell(fh); fclose(fh); return size; } return -1; //error } void calculateChecksum(char * filename, char […]

在.so中混合使用c / c ++和汇编时避免文本重定位

我试图从混合c,c ++和汇编的.so中删除所有文本重定位。 对于c / c ++ -fpic负责PIC。 在Android ARM目标上,我们可以从c / c ++调用导出的asm函数,而不会导致文本重定位。 但是在我们的实现中,我们有必须可以从C ++和程序集访问的数据数组。 在C ++上,它是一个普通的旧数组,即extern “C” { __declspec(align(32)) int16_t myarray[256]; } 在asm方面我们使用.global myarray 。 第二个我们在asm侧使用这样的符号,我们在最终的.so中看到文本重定位,这是通过scanelf和readelf可见的。 api模式23中的Android L加载器将拒绝加载这样的.so。 问题: – 这个问题值得期待吗? – 是否在C或asm方面使用了一些特殊声明以确保没有文本重定位? 编辑 :最小的例子会有用吗?

为什么在调试时初始化函数中的字符串不像int那样工作

所以我今天尝试调试一些简单的C程序; 第一个是 int main(){ int a ,b ; return 0 ; } 在解编的时候给了我什么 push ebp mov ebp,esp sub esp,008h 因为我需要有8个字节来存储当前堆栈帧中的a和b,因为它们是局部变量! 但是当我尝试同样的字符串说 int main() { char greeting[12] = “Pwnit2Ownit”; return 0; } 在解编的时候给了我什么 push ebp mov ebp,esp sub esp,0DCh 0DCh是220,但由于字符串只有12个字节长不应该 sub esp,0DCh 是 sub esp,00ch 相反? 任何人都可以分享关于如何将字符串存储在内存中以及稍后通过汇编[优先指令]访问的链接,如果它的长度很大,那么存储在内存中的字符串问候因为我们无法将所有内容存储在堆栈中