어셈블리 빌더를 개발하고 있는데, 목적 파일을 링크하는 데서 오류가 발생합니다.

HDNua의 이미지

안녕하세요. 복학 전까지 공부하고 있는 휴학생입니다.

NASM을 이용해 어셈블리를 강의하는 글을 쓰려고 합니다.
그런데 NASM 강의 자료를 보면 모두 명령 프롬프트를 이용하여 다음과 같이 입력해주어야 합니다.

nasm -f win32 test_object.obj
gcc -o output.exe test_object.obj

저는 이런 과정이 독자를 혼란스럽게 만들 것 같다고 생각하고, 이런 부분은 웬만하면 저자가 도구를 제공해야 한다고 생각합니다.
명령 프롬프트에 직접 입력하는 과정은 이게 안 되는 경우에만 어쩔 수 없이 해야 하는 것이고, 언어와 직접적으로 관련이 없는 부분은 강요하고 싶지 않습니다.
그래서 저는 NASM으로 작성한 어셈블리 소스 파일을 바로 빌드할 수 있게 하는, QuickNASM이라는 프로그램을 C#을 이용하여 작성하려고 했습니다.
(완성되었을 때의 예상 이미지를 파일로 첨부하였습니다.)

그리고 다른 문서의 입출력 파일을 그대로 가져다쓰는 것이 저작권 등의 문제가 발생할 수 있다는 점,
제가 제공하기 원하는 함수와 사용 방법이 다를 수 있어 제가 설명하고자 하는 내용에 부합하지 않을 수 있다는 점 때문에,
입출력 함수도 제가 제공하려고 합니다. 물론 뿌리부터 싹 다 만들겠다는 건 아니고 C의 표준 입출력 함수에 대한 래퍼 함수를 생각하고 있습니다.

handy_io.c
-----
#include <stdio.h>
...
int print_num(int num) {
 return printf("%d", num);
}
int print_str(const char *str) {
 return printf("%d", (const char *)str);
}
...

아래는 이를 위해 제가 작성한 메서드 목록입니다. (프로젝트도 첨부하겠습니다.)

MainFormImple.cs
-----
using System;
...
 
using System.IO;
using System.Diagnostics;
 
namespace QuickNASM
{
    public partial class MainForm
    {
        // constants
 
        // fields
        string filename = "";
 
        // methods
        void Log(string text)
        {
            LogBox.Text += (text + Environment.NewLine);
            LogBox.SelectionStart = LogBox.Text.Length;
            LogBox.ScrollToCaret();
        }
 
        #region Private Event Handler List
        // 이벤트 핸들러의 목록을 정의합니다.
 
        ...
 
        bool Assemble()
        {
            try
            {
                if (Save() == false)
                    throw new Exception("cannot save file " + filename);
 
                string assemblyName = Handy.String.GetFileName(filename); // c:\test\dir\program.exe와 같은 문자열에서 program을 추출합니다.
                string nasmPath = "C:\\nasm\\nasm";
                string commandParam = "-f win32 " + filename;
                Process proc = Process.Start(nasmPath, commandParam); // nasm 실행 파일을 실행하고 프로세스가 끝날 때까지 대기합니다.
                proc.WaitForExit();
 
                if (proc.ExitCode != 0) // 프로세스가 정상적으로 종료되지 않았다면 예외 처리합니다.
                    throw new Exception("process did not end with code 0");
 
                Log("Assemble complete");
                return true;
            }
            catch (Exception ex)
            {
                Log(ex.Message);
                return false;
            }
        }
        bool Link()
        {
            try
            {
                string linkerPath = "C:\\MinGW\\bin\\gcc.exe";
                string execName = "out";
                string outputPath = Environment.CurrentDirectory + "\\" + execName + ".exe";
                string objectPath = Environment.CurrentDirectory + "\\" + Handy.String.GetFileName(filename) + ".obj";
                string commandParam = string.Format("-o {0} {1}", outputPath, objectPath);
                Process proc = Process.Start(linkerPath, commandParam); // out.exe 실행 가능한 목적 파일이 생성됩니다.
                proc.WaitForExit();
 
                if (proc.ExitCode != 0)
                    throw new Exception("process did not end with code 0");
 
                Log("Link complete");
                return true;
            }
            catch (Exception ex)
            {
                Log(ex.Message);
                return false;
            }
        }
        bool Build()
        {
            try
            {
                if (Assemble() == false)
                    throw new Exception("Assemble failed");
                if (Link() == false)
                    throw new Exception("Linked failed");
                Log("Build complete");
                return true;
            }
            catch (Exception ex)
            {
                Log(ex.Message);
                return false;
            }
        }
        void Run()
        {
            Log("Running");
        }
        void BuildAndRun()
        {
            Build();
            Run();
        }
 
        #endregion Private Event Handler List
    }
}

그런데 어셈블까지는 잘 수행하는 것 같으나, 링크 과정에서 다음과 같은 오류가 발생합니다.

경고 창 타이틀: ld.exe - 시작 지점 없음
경고 창 내용: 프로시저 시작 지점 __printf___을(를) DLL libintl-8.dll에서 찾을 수 없습니다.

이 문제를 해결해보려고 한참을 인터넷을 뒤졌지만, 검색 능력이 부족한지 찾을 수가 없더군요.
먼저 질문을 하기 전에 제가 작업하고 있는 환경을 설명하겠습니다.
1. nasm 공식 홈페이지인 http://www.nasm.us/ 에서 내려받은 nasm 설치 도구로 nasm을 설치하여 사용합니다.
2. MinGW를 설치해서 gcc의 링크 기능을 이용해 링크합니다.

Visual Studio의 link.exe 파일도 사용해보려고 했으나 잘 안 되더군요. (/로 시작하는 이상한 옵션이 없다던가 하는 문제였는데 잘 기억이 안 납니다)
사실 지금 어떤 것을 질문드려야 할 지도 혼란스러운데, 정리해서 말해보겠습니다.

1. main 함수의 정의가 없다면 이해하겠는데, __printf___ 함수의 시작 지점 같은 걸 물어보니 혼란스럽습니다.
정말 이상한 질문인데.. 이런 상황은 어떻게 해결해야 할까요? (제가 물어놓고 제가 설명을 못 하니 답답합니다..)

2. printf와 같은 표준 함수가 정의되어있는 목적 파일을 링크하는 것이 이치에 맞는 것 같은데, 이것을 어떻게 해야 할 지 궁금합니다.

3. 자식 프로세스가 표준 스트림에 뱉은 메시지를 부모 프로세스가 가져올 수 있을까요?
파이프라인이라고 부등호 기호를 이용하여 스트림을 돌리는 방법을 들었는데, 이것을 응용해서 Process.Start 함수의 인자 문자열에 같이 넘겼지만 잘 안 됐습니다.
out.txt 파일에 출력해놓고 프로세스가 끝날때까지 기다렸다가 out.txt 파일이 생성되면 StreamReader로 out.txt 파일을 읽는 방법을 생각했었는데요.
(사진을 보면 로그 화면이 있는데, Visual Studio에서처럼 빌드 오류가 발생할 때 뱉는 메시지를 이곳에 출력하고 싶어서 꼭 필요합니다.)

리스트 뷰와 같은 내용은 제가 시간을 들여 할 수 있으나, 링커 사용 방법이 정말 어렵네요.
질문이 많이 혼란스럽습니다. 읽어주신 모든 분들 감사합니다.

File attachments: 
첨부파일 크기
Package icon QuickNASM.zip511.85 KB
Image icon 1.png39.78 KB
익명 사용자의 이미지

printf자체도 하나의 함수이며 내부적으로는 시스템콜을 이용합니다.
vc에서는 crt 관련 라이브러리에 printf가 구현되어있으니 참고해보세요.

HDNua의 이미지

소중한 답변 감사합니다. 찾아볼게요.

저는 이렇게 생각했습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.