Tag: assembly

gcc:命令行参数在汇编代码中引用不同

我习惯看到(约定(A))引用的命令行参数: pushl %ebp movl %esp, %ebp movl (%ebp), %eax # argc movl 4(%ebp), %ebx # pointer to argv[0] string movl 8($ebp), %ecx # pointer to argv[1] string 有时,我看到列表的偏移量为8,这不是(主要)问题。 我在程序中注意到的是这个翻译和引用,我很困惑,得到argv[1] (约定(B)): movl 0xc(%ebp), %eax # pointer to a pointer to argv[0] (argc is at offset 8) addl $0x4, %eax # argv[1] is a pointer at offset […]

从C调用x86-64上的NASM时返回值错误

我在Linux 64位上学习NASM,并且一直在尝试实现一些代码示例。 但是我在下面的示例中遇到了问题。 函数donothing在NASM中实现,并且应该在用C实现的程序中调用: 文件main.c: #include #include int donothing(int, int); int main() { printf(” == %d\n”, donothing(1, 2)); return 0; } 提交first.asm global donothing section .text donothing: push rbp mov rbp, rsp mov eax, [rbp-0x4] pop rbp ret 什么不做只不过是返回第一个参数的值。 但是当调用donothing时,将打印值0而不是1.我尝试了rpb + 0x4,但它也不起作用。 我使用以下命令编译文件: nasm -f elf64 first.asm && gcc first.o main.c 使用gcc -s在C中编译函数’test’,生成的汇编代码用于获取参数类似于donothing: int test(int […]

在汇编程序AMD64中,我调用fprintf,但它保持无限循环

我对fprintf有一个问题,我无法掌握。 也许你可以找到解决这个问题的方法。 你看,当我调用fprintf它开始无限循环,没有充分的理由。 我不知道这里发生了什么,所以也许你可以帮我一臂之力。 String_int: db 91; “[” db 37; “%” db 115;”i” db 93; “]” db 0; “end_string” w_IN_ASCII: db 119; “w” db 0; “end_string” mov rdi, FILE_LOCATION; mov rsi, w_IN_ASCII; call fopen; mov r15, rax; cmp r15, 0; (with this I can be sure it is not a NULL) je .endProgram; mov rdi, […]

如何从汇编例程调用C函数并使用nasm和gcc链接C和汇编文件

我想从汇编中调用至少1个C函数。 这是因为我从头开始做我自己的小操作系统(无中生有)。 我想从我的启动加载程序调用c函数的原因。 我可以理解集会,但写自己的程序很差。 因此,如果我可以将控制从assembly程序转移到c程序,我的工作就变得更容易了。 那么如何将程序集pgm和C程序文件链接成一个。 即使文件大小超过512字节,也可以。 我在mingw的帮助下在Windows 7上这样做。 我的c编译器是gcc ,汇编器是nasm 。

C / C ++在引擎盖下按值返回struct

(这个问题特定于我的机器的架构和调用约定,Windows x86_64) 我不记得我在哪里读过这个,或者我是否正确地回忆过它,但是我听说过,当一个函数应该按值返回一些结构或对象时,它会将它填入rax (如果对象可以适合64位的寄存器宽度)或传递指向结果对象所在的指针(我猜在调用函数的堆栈帧中分配)在rcx ,它将执行所有常规初始化,然后是mov rax, rcx为回程。 就是这样的 extern some_struct create_it(); // implemented in assembly 真的会有一个秘密参数 extern some_struct create_it(some_struct* secret_param_pointing_to_where_i_will_be); 我的记忆对我有用,还是我不正确? 如何通过函数的值返回大对象(即宽度超过寄存器宽度)?

为什么在调用printf时会覆盖EDX的值?

我写了一个简单的汇编程序: section .data str_out db “%d “,10,0 section .text extern printf extern exit global main main: MOV EDX, ESP MOV EAX, EDX PUSH EAX PUSH str_out CALL printf SUB ESP, 8 ; cleanup stack MOV EAX, EDX PUSH EAX PUSH str_out CALL printf SUB ESP, 8 ; cleanup stack CALL exit 我是NASM汇编程序和GCC,用于将目标文件链接到linux上的可执行文件。 本质上,该程序首先将堆栈指针的值放入寄存器EDX,然后将该寄存器的内容打印两次。 但是,在第二次printf调用之后,打印到stdout的值与第一个不匹配。 这种行为似乎很奇怪。 […]

gcc参数寄存器溢出x86-64

我正在尝试使用x86-64程序集。 编译了这个虚函数: long myfunc(long a, long b, long c, long d, long e, long f, long g, long h) { long xx = a * b * c * d * e * f * g * h; long yy = a + b + c + d + e + f + g + […]

与astype(int)相比,numpy around / rint slow

所以,如果我有像x=np.random.rand(60000)*400-200 。 iPython的%timeit说: x.astype(int)需要0.14ms np.rint(x)和np.around(x)需要1.01ms 请注意,在rint和around情况下,您仍然需要花费额外的0.14ms来做最终的astype(int) (假设这是你最终想要的)。 问题:我认为大多数现代硬件都能够在同等时间内完成两项操作。 如果是这样的话,为什么numpy需要花费8倍的时间来进行舍入? 碰巧我对算术的准确性并不十分挑剔,但我看不出如何利用numpy(我正在做杂乱的生物学而不是粒子物理学)。

将ARM asm反编译回C

几年前我编写了一个很好的ARM汇编程序,多年来它在其设计的ARM嵌入式系统上完美地完成了它的工作。 现在,现在是将它移植到非ARM系统的时候了,我想知道是否有工具或某种方法来获取我原来的ARM汇编源并从中获取一个rudimentory C文件。 我可以在几天内自己做,但是有一个起点会很好。 如果应用程序或方法是免费的,那就更好了:) 有什么建议?

将指令的目标地址保持在寄存器中,直到指令退出为止

我想在XeonE5 Sandy Bridge上使用精确的基于事件的采样(PEBS)来记录特定事件的所有地址(例如缓存未命中)。 但是, Core TM i7处理器和Intel®XeonTM5500处理器性能分析指南 (第24页)包含以下警告: 由于PEBS机制在指令完成时捕获寄存器的值,因此无法重建以下类型的加载指令(Intel asm约定)的解除引用的地址。 MOV RAX, [RAX+const] 这种指令主要与指针追逐有关 mystruc = mystruc->next; 这是捕获存储器指令地址的这种方法的重大缺点。 根据objdump,我在程序中有许多该表单的加载指令。 有什么办法可以避免吗? 由于这是一个特定于英特尔的问题,解决方案不必以任何方式移植,它只需要工作。 我的代码是用C语言编写的,我理想地寻找编译器级解决方案(gcc或icc),但欢迎任何建议。 一些例子: mov 0x18(%rdi),%rdi mov (%rcx,%rax,8),%rax 在这两种情况下,在指令退出之后(因此当我查看寄存器值以确定我加载到/来自的位置时)地址的值(在这些示例中分别为%rdi + 18和%rcx + 8 * %rax )被mov的结果覆盖。