的执行指令数不同

的执行指令数不同

本文介绍了Hello World 程序 Nasm Assembly 和 C 的执行指令数不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a simple debugger (using ptrace : http://pastebin.com/D0um3bUi) to count the number of instructions executed for a given input executable program. It uses ptrace single step execution mode to count instructions.

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

For that when the program 1)'s executable (a.out from gcc main.c) is given as input to my test debuggger it prints around 100k as instructions executed. When I use -static option it gives 10681 instructions.

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

Now in 2) I create an assembly program and use NASM for compiling and linking and then when this executable is given as test debuggers input it is showing 8 instructions as the count and which is apt.

由于在运行时将程序与系统库链接,程序 1) 中执行的指令数量很高?使用 -static 并将计数减少 1/10.如何确保指令计数仅是程序 1) 中主要函数的指令计数以及程序 2) 向调试器报告的方式?

The number of instructions executed in program 1) is high because of linking the program with system library's at runtime ? used -static and which reduces the count by a factor of 1/10. How can I ensure that the instruction count is only that of the main function in Program 1) and which is how Program 2) is reporting for the debugger?

1)

#include <stdio.h>

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

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

I use gcc to create the executable.

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

推荐答案

是的,动态链接加上 CRT(C 运行时)启动文件.

Yep, dynamic linking plus CRT (C runtime) startup files.

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

这样就留下了 CRT 启动文件,它们在调用 main 之前和之后做一些事情.

So that just left the CRT start files, which do stuff before calling main, and after.

如何确保指令数只是程序1)中的main函数的指令数`

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

Measure an empty main, then subtract that number from future measurements.

除非您的指令计数器更智能,并且查看可执行文件中的符号以了解它正在跟踪的进程,否则它将无法分辨哪些代码来自何处.

Unless your instruction-counters is smarter, and looks at symbols in the executable for the process it's tracing, it won't be able to tell which code came from where.

这就是程序 2) 向调试器报告的方式.

那是因为该程序中没有其他代码.并不是你以某种方式帮助调试器忽略了一些指令,而是你制作了一个没有任何指令的程序,你没有自己放在那里.

That's because there is no other code in that program. It's not that you somehow helped the debugger ignore some instructions, it's that you made a program without any instructions you didn't put there yourself.

如果您想查看运行 gcc 输出时实际上发生了什么,gdb a.out, b _start, r 和单步.一旦你深入调用树,你就是概率.想要使用 fin 来完成当前函数的执行,因为您不想单步执行 100 万条指令,甚至 10k.

If you want to see what actually happens when you run the gcc output, gdb a.out, b _start, r, and single-step. Once you get deep in the call tree, you're prob. going to want to use fin to finish execution of the current function, since you don't want to single-step through literally 1 million instructions, or even 10k.

相关:如何确定在 C 程序中执行的 x86 机器指令的数量? 显示 perf stat 将在 NASM 程序中计算总共 3 条用户空间指令mov eax, 231/syscall,链接到一个静态可执行文件中.

related: How do I determine the number of x86 machine instructions executed in a C program? shows perf stat will count 3 user-space instructions total in a NASM program that does mov eax, 231 / syscall, linked into a static executable.

这篇关于Hello World 程序 Nasm Assembly 和 C 的执行指令数不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 08:24