ブログ

割とコンピュータよりの情報をお届けします。

2018年11月

Visual C++プロジェクトでアセンブリ出力という機能

Visual C++でプロジェクトを作っていれば,アッセンブリ出力という機能が使えることを知った。

プロジェクトのプロパティで[C/C++]->[すべてのオプション]->アッセンブリの出力で「アッセンブリコード、コンピューター語、ソースコード(/FAcs)」を出力するようにすれば,

#include "stdafx.h"


int main()
{
    signed char a;
    short b;
    int c;

    a = -10;
    b = 20;
    c = 30;
    c = a + b + c;
    return 0;
}

このコードが,*.codファイルに出力される。

; Listing generated by Microsoft (R) Optimizing Compiler Version 19.13.26129.0 

    TITLE    E:\start001\ConsoleApplication1\ConsoleApplication1.cpp
    .686P
    .XMM
    include listing.inc
    .model    flat

INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES

PUBLIC    _main
EXTRN    __RTC_InitBase:PROC
EXTRN    __RTC_Shutdown:PROC
;    COMDAT rtc$TMZ
rtc$TMZ    SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ    ENDS
;    COMDAT rtc$IMZ
rtc$IMZ    SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
rtc$IMZ    ENDS
; Function compile flags: /Odtp /RTCsu /ZI
; File c:\start001\consoleapplication1\consoleapplication1.cpp
;    COMDAT _main
_TEXT    SEGMENT
_c$ = -32                        ; size = 4
_b$ = -20                        ; size = 2
_a$ = -5                        ; size = 1
_main    PROC                        ; COMDAT

  00000    55         push     ebp
  00001    8b ec         mov     ebp, esp
  00003    81 ec e4 00 00
    00         sub     esp, 228        ; 000000e4H
  00009    53         push     ebx
  0000a    56         push     esi
  0000b    57         push     edi
  0000c    8d bd 1c ff ff
    ff         lea     edi, DWORD PTR [ebp-228]
  00012    b9 39 00 00 00     mov     ecx, 57            ; 00000039H
  00017    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH
  0001c    f3 ab         rep stosd

  0001e    c6 45 fb f6     mov     BYTE PTR _a$[ebp], -10    ; fffffff6H

  00022    b8 14 00 00 00     mov     eax, 20            ; 00000014H
  00027    66 89 45 ec     mov     WORD PTR _b$[ebp], ax

  0002b    c7 45 e0 1e 00
    00 00         mov     DWORD PTR _c$[ebp], 30    ; 0000001eH

  00032    0f be 45 fb     movsx     eax, BYTE PTR _a$[ebp]
  00036    0f bf 4d ec     movsx     ecx, WORD PTR _b$[ebp]
  0003a    03 45 e0     add     eax, DWORD PTR _c$[ebp]
  0003d    03 c8         add     ecx, eax
  0003f    89 4d e0     mov     DWORD PTR _c$[ebp], ecx

  00042    33 c0         xor     eax, eax

  00044    5f         pop     edi
  00045    5e         pop     esi
  00046    5b         pop     ebx
  00047    8b e5         mov     esp, ebp
  00049    5d         pop     ebp
  0004a    c3         ret     0
_main    ENDP
_TEXT    ENDS
END

x64の場合には以下のようになる

; Listing generated by Microsoft (R) Optimizing Compiler Version 19.13.26129.0 

include listing.inc

INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES

PUBLIC    main
EXTRN    _RTC_InitBase:PROC
EXTRN    _RTC_Shutdown:PROC
;    COMDAT pdata
pdata    SEGMENT
$pdata$main DD    imagerel $LN3
    DD    imagerel $LN3+82
    DD    imagerel $unwind$main
pdata    ENDS
;    COMDAT rtc$TMZ
rtc$TMZ    SEGMENT
_RTC_Shutdown.rtc$TMZ DQ FLAT:_RTC_Shutdown
rtc$TMZ    ENDS
;    COMDAT rtc$IMZ
rtc$IMZ    SEGMENT
_RTC_InitBase.rtc$IMZ DQ FLAT:_RTC_InitBase
rtc$IMZ    ENDS
;    COMDAT xdata
xdata    SEGMENT
$unwind$main DD    05051c01H
    DD    010a030dH
    DD    070030025H
    DD    05002H
xdata    ENDS
; Function compile flags: /Odtp /RTCsu /ZI
; File e:\start001\consoleapplication1\consoleapplication1.cpp
;    COMDAT main
_TEXT    SEGMENT
a$ = 4
b$ = 36
c$ = 68
main    PROC                        ; COMDAT

$LN3:
  00000    40 55         push     rbp
  00002    57         push     rdi
  00003    48 81 ec 28 01
    00 00         sub     rsp, 296        ; 00000128H
  0000a    48 8b ec     mov     rbp, rsp
  0000d    48 8b fc     mov     rdi, rsp
  00010    b9 4a 00 00 00     mov     ecx, 74            ; 0000004aH
  00015    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH
  0001a    f3 ab         rep stosd

  0001c    c6 45 04 f6     mov     BYTE PTR a$[rbp], -10

  00020    b8 14 00 00 00     mov     eax, 20
  00025    66 89 45 24     mov     WORD PTR b$[rbp], ax

  00029    c7 45 44 1e 00
    00 00         mov     DWORD PTR c$[rbp], 30

  00030    0f be 45 04     movsx     eax, BYTE PTR a$[rbp]
  00034    0f bf 4d 24     movsx     ecx, WORD PTR b$[rbp]
  00038    8b 55 44     mov     edx, DWORD PTR c$[rbp]
  0003b    03 d0         add     edx, eax
  0003d    8b c2         mov     eax, edx
  0003f    03 c8         add     ecx, eax
  00041    8b c1         mov     eax, ecx
  00043    89 45 44     mov     DWORD PTR c$[rbp], eax

  00046    33 c0         xor     eax, eax

  00048    48 8d a5 28 01
    00 00         lea     rsp, QWORD PTR [rbp+296]
  0004f    5f         pop     rdi
  00050    5d         pop     rbp
  00051    c3         ret     0
main    ENDP
_TEXT    ENDS
END

≫ 続きを読む

2018/11/24 コンピュータ   TakeMe

.NET Framework Semaphoreを使ってみた

.NET Frameworkでは結構前のバージョンからSystem.Threading.Semaphoreなるものが使えるようになっている。

例えば次のようなコードだが,Semaphoreをnamespaceに使ってしまったので,System.Threading.Semaphoreをいちいち書いている。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Threading;

namespace Semaphore
{
    class Program
    {
        private static System.Threading.Semaphore sem;

        static void Main(string[] args)
        {
            sem = new System.Threading.Semaphore(0, 1);

            for (int i = 1; i <= 10; i++)
            {
                Thread t = new Thread(new ParameterizedThreadStart(Worker));
                t.Start(i);
            }

            Thread.Sleep(500);

            Console.WriteLine("Main thread calls Release(1).");
            sem.Release(1);

            Console.WriteLine("Main thread exits.");
        }

        private static void Worker(object num)
        {
            Console.WriteLine("Thread {0} started " +
                "and waits for the semaphore.", num);
            sem.WaitOne();
            {
                // ここに一スレッドごと実行したい内容
                Console.WriteLine("Thread {0} enters the semaphore.", num);
            }
            Int32 count = sem.Release(1);
            Console.WriteLine("Thread {0} releases the semaphore. " +
                "The previous semaphore cout: {1}",
                num, count);
        }
    }
}

実はmutexより速いが,lockなどより時間がかかるらしい。

≫ 続きを読む

2018/11/18 コンピュータ   TakeMe