一尘不染

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

linux

我有一个简单的调试器(使用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

阅读 289

收藏
2020-06-02

共1个答案

一尘不染

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

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

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

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

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

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

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

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

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

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

2020-06-02