section .text global _start msg db 'hello,world', 0x0A msglen equ $ - msg _start: mov ecx, msg mov edx, msglen mov eax, 4 mov ebx, 1 int 0x80 mov eax, 1 mov ebx, 0 int 0x80 |
$ od -A x -t x1z -v hello01
hello.c #include<stdio.h> void main(){ printf("hello,world\n"); } 普通にコンパイルして実行ファイルhello02を出力するには gcc hello.c -o hello02 逆アセンブルするには gcc main.c -g -c でコンパイルするとオブジェクトファイルmain.oが作成されるのでこれを objdump main.o -S で見ることができる。 |
;*********************************** ; Assembly Programming on X86 Linux ; cxレジスタを16bitのカウンタとして扱う ; c3番地からc0番地までをcxレジスタの数値表示用の文字コードを格納し ; 16進数で画面に表示する ;*********************************** section .data c3: db 0x00 ; cxレジスタ3桁目の文字コード c2: db 0x00 ; cxレジスタ2桁目の文字コード c1: db 0x00 ; cxレジスタ1桁目の文字コード c0: db 0x00 ; cxレジスタ0桁目の文字コード db 0x0A ; 改行コード msglen equ $-c3 section .text ; テキストセクションにはプログラムを記述 extern _n2char ;alの16進数1桁を文字コードにする global _start _start: ; プログラム先頭ラベル xor cx,cx ; cxレジスタ0クリア label1: inc cx ; inc命令ではcary フラグはonにならないので注意 jz label2 mov ax,cx call _n2char mov [c0],al mov al,ah call _n2char mov [c2],al mov ax,cx ror ax,4 call _n2char mov [c1],al mov al,ah call _n2char mov [c3],al push ecx ; ecx退避 mov ecx,c3 ; 出力するデータの先頭アドレスをecxにセット mov edx,msglen ; 出力するデータの長さをedxにセット mov eax,4 ; システムコールwrite()の番号をeaxにセット mov ebx,1 ; ファイルディスクリプタを標準出力にする int 0x80 ; システムコール pop ecx ; ecx復帰 jmp label1 label2: mov eax,1 ; システムコールclose()の番号をeaxにセット mov ebx,1 ; クローズするファイルディスクリプタの番号 int 0x80 ; システムコール |
section .text global _n2char global _c2num ;***************************************************** ; 機能ALレジスタ 0からfまでの16進数を文字コードにする ; 入力AL 出力AL ; 例1. 入力AL=0x05 出力AL=0x35 ; 例2. 入力AL=0x0A 出力AL=0x61 ;**************************************************** _n2char: and al,0x0F ; 上位4bit0クリア cmp al,0x09 ; al - 0x09 jg n2_1 ; al > 0x09 then n2_1 or al,0x30 ; ret n2_1: sub al,0x09 or al,0x60 ret ;***************************************************** ; 機能ALレジスタ 数値0からfまでの文字コードを数値にする ; 入力AL 出力AL ; 例1. 入力AL=0x35 出力AL=0x05 ; 例2. 入力AL=0x41 出力AL=0x0a ; 例2. 入力AL=0x61 出力AL=0x0a ;**************************************************** _c2num: push ax and al,0xf0 cmp al,0x30 je c2_1 cmp al,0x40 je c2_2 cmp al,0x60 je c2_2 pop ax ret c2_1: pop ax and al,0x0f ret c2_2: pop ax and al,0x0f add al,0x09 ret |
#include <stdio.h> extern int asm_sub(int a, int b); int main(){ int a, b; a = 3; /*第一引数*/ b = 2; /*第ニ引数*/ int ans = asm_sub(a, b); printf(”%d\ n”, ans); return 0; } |
section .text global asm_sub asm_sub: mov eax,[esp+4] ; 第 1 引数を eax へ sub eax,[esp+8] ; eaxから第2引数を減算 , 戻り値は eax ret |
/********************************************* * 2147300001から2147483647 * の間の素数を求める * ******************************************/ #include<stdio.h> #include<time.h> #include<math.h> extern int p_chk(int a,int s); /* 判定値=p_chk(int a,int s);*/ /* a=判定したい素数 s=素数の平方根の整数部 */ /* 判定値1 素数,0 素数以外*/ void main(){ long cpu_time; double sec; int s; int p; int a=2147300001; while(a >=0){ s=(int)sqrt(a); p=p_chk(a,s); if(p!=0){ printf("%d\n",a); } a++; } /*cpu時間をチェック*/ cpu_time=clock(); /*秒に変換*/ sec=(double)cpu_time /CLOCKS_PER_SEC; printf("%f秒\n",sec); } |
;******************************************************* ; 素数チェックモジュール ; 入力 第一引数[esp+4] 素数判定する数 ; 第ニ引数[esp+8] 素数判定する数の平方根の整数部 ; [esp+4] / [esp+8] ; ; 出力 判定 eax !=0 素数 0 素数ではない ;******************************************************* section .data kensa_no: dd 0 ; 第1引数(検査する数) sqrt_no: dd 0 ; 第2引数 (第1引数の平方根) section .text global p_chk p_chk: mov ecx,2 mov eax,[esp+8] mov [sqrt_no],eax mov eax,[esp+4] mov [kensa_no],eax label1: mov eax,[kensa_no] ;第1引数をeaxへ xor edx,edx div ecx ; 商 eax = edx:eax / ecx ; 剰余 edx cmp edx,0 jz label2 inc ecx cmp ecx,[sqrt_no] jbe label1 label2: mov eax,edx ;(余りをeaxにセット) ret |