当前位置: 首页 > 面试题库 >

Hello World程序Nasm Assembly和C的已执行指令数不同

许正平
2023-03-14
问题内容

我有一个简单的调试器(使用ptrace:http :
//pastebin.com/D0um3bUi)来计算为给定输入可执行程序执行的指令数。它使用ptrace单步执行模式来计数指令。

为此,当将程序1)的可执行文件(来自gcc
main.c的a.out)作为输入提供给我的测试调试器时,它将作为执行的指令打印约100k。当我使用-static选项时,它会给出10681条指令。

现在在2)中,我创建一个汇编程序,并使用NASM进行编译和链接,然后当此可执行文件作为测试调试器的输入提供时,它显示8条指令作为计数,这是适当的。

由于在运行时将程序与系统库的链接起来,因此程序1)中执行的指令数量很高。使用了-
static,将计数减少了1/10。我如何确保指令计数仅是程序1)中主要功能的计数,而程序2)是如何为调试器报告的?

1)

#include <stdio.h>

int main()
{
    printf("Hello, world!\n");
    return 0;
}

我使用gcc创建可执行文件。

2)

; 64-bit "Hello World!" in Linux NASM

global _start            ; global entry point export for ld

section .text
_start:

    ; sys_write(stdout, message, length)

    mov    rax, 1        ; sys_write
    mov    rdi, 1        ; stdout
    mov    rsi, message    ; message address
    mov    rdx, length    ; message string length
    syscall

    ; sys_exit(return_code)

    mov    rax, 60        ; sys_exit
    mov    rdi, 0        ; return 0 (success)
    syscall

section .data
    message: db 'Hello, world!',0x0A    ; message and newline
    length:    equ    $-message        ; NASM definition pseudo-

我用:

nasm -f elf64 -o main.o -s main.asm  
ld -o main main.o

问题答案:

由于在运行时将程序与系统库链接在一起,因此程序1)中执行的指令数量很高?

是的,动态链接以及CRT(C运行时)启动文件。

使用-static,并将计数减少1/10。

这样就剩下了CRT启动文件,这些文件在调用之前main和之后进行处理。

如何确保指令计数仅是程序1)中主要功能的计数?

测量一个空的main,然后从将来的测量中减去该数字。

除非您的指令计数器更聪明,并且在可执行文件中查看其跟踪过程的符号,否则它将无法分辨出哪个代码来自何处。

以及程序2)向调试器报告的方式。

这是因为有 在该程序中没有其他的代码。并不是说您以某种方式帮助调试器忽略了某些指令,而是您在编写程序时没有自己未放入的任何指令。

如果你想看看 真正 发生在你运行GCC的输出gdb a.outb _startr,和单步执行。一旦深入了解通话树,您就很有可能了。fin因为您不想单步执行一百万条指令甚至一万条指令,所以将要使用它来完成当前功能的执行。



 类似资料:
  • 问题内容: 指令功能的执行顺序是什么?该文档似乎没有解决此问题。 防爆 template / templateUrl(已评估) 控制器 编译 链接 从下面的答案中:http ://plnkr.co/edit/79iyKSbfxgkzk2Pivuak(插件显示嵌套和兄弟指令) 模板被解析 (在编译中对模板所做的更改会扩展到链接功能) 问题答案: 预链接功能:在链接子元素之前执行。执行DOM转换并不安

  • 我开始写一个Discord机器人,但我已经设法遇到了一个问题。我只是写了他写的东西,做了一些小改动,不会对程序产生太大影响。我有两个类,主类只获取bot的令牌,然后使用 下面是MyBot.cs: 它可以连接,机器人也可以在线。这是我的控制台中的输出: 当我现在打字的时候。一般来说,什么都不会发生。控制台中没有,一般情况下也没有。我已经看过了,但它并没有解决我的问题 编辑:我知道我应该使用Comma

  • 我决定回到编程(特别是C),为此我开始开发命令行解析器。最终,目标是将其变成一个简单的类,我可以在未来的一些项目中导入。 这个测试程序只是简单地列出它收到的参数数量,然后打印出来,每行一个,然后退出。 这是我的代码: 以下是终端中发生的情况: 为什么它不按它应该的那样打印论点?它清楚地识别论点,那么问题是什么?我肯定我在这里错过了一些明显的东西。

  • 问题内容: 我应该如何从我的程序中运行另一个程序?我需要能够将数据写入启动的程序中(并可能从中读取) 我不确定这是否是标准的C函数。我需要应该在Linux下工作的解决方案。 问题答案: 您要使用。它为您提供了一个单向管道,您可以使用该管道访问程序的stdin和stdout。 popen是现代unix和类似unix的操作系统的标准配置,其中Linux是其中之一:-) 类型 在终端上阅读有关它的更多信

  • 我对指令流水线有些怀疑。 我有一个集会

  • 我有一个在macOS上绕道的自定义实现和一个使用它的测试应用程序,它是用C编写的,为macOSx86_64编译,运行在英特尔i9处理器上。 该实现与多种功能一起工作良好。但是,如果我绕,我会遇到奇怪的行为:通过绕道pthread_create生成的线程不执行指令。我可以逐个逐步执行说明,但一旦我,它就不会进展。不涉及互斥锁或同步,函数的结果是 0(成功)。关闭绕道的完全相同的应用程序工作正常,因此