nasm简单实例

Sample nasm programs

Specifically: for Intel I-32, e.g. 386, 486, pentium

Specifically: for use with gcc with its libraries and gdb

Specifically: simple nasm syntax using "C" literals

Specifically: showing an equivalent "C" program

Generally, for Linux and possibly other Unix on Intel

Generally, not using 8-bit or 16-bit for anything

Contents

Makefile for samples shown below hello.asm basic stand alone program printf1.asm basic calling printf printf2.asm more types for printf intarith.asm simple integer arithmetic fltarith.asm simple floating point arithmetic

hello.asm basic stand alone program

  The nasm source code is hello.asm   The result of the assembly is hello.lst   Running the program produces output hello.out   This program demonstrates basic text output to a screen.
  No "C" library functions are used.
  Calls are made to the operating system directly. (int 80 hex)

;  hello.asm  a first program for nasm for Linux, Intel, gcc
;
; assemble:	nasm -f elf -l hello.lst  hello.asm
; link:		gcc -o hello  hello.o
; run:	        hello 
; output is:	Hello World 

	SECTION .data		; data section
msg:	db "Hello World",10	; the string to print, 10=cr
len:	equ $-msg		; "$" means "here"
				; len is a value, not an address

	SECTION .text		; code section
        global main		; make label available to linker 
main:				; standard  gcc  entry point
	
	mov	edx,len		; arg3, length of string to print
	mov	ecx,msg		; arg2, pointer to string
	mov	ebx,1		; arg1, where to write, screen
	mov	eax,4		; write sysout command to int 80 hex
	int	0x80		; interrupt 80 hex, call kernel
	
	mov	ebx,0		; exit code, 0=normal
	mov	eax,1		; exit command to kernel
	int	0x80		; interrupt 80 hex, call kernel
   

printf1.asm basic calling printf

  The nasm source code is printf1.asm   The result of the assembly is printf1.lst   The equivalent "C" program is printf1.c   Running the program produces output printf1.out   This program demonstrates basic use of "C" library function  printf.
  The equivalent "C" code is shown as comments in the assembly language.

; printf1.asm   print an integer from storage and from a register
; Assemble:	nasm -f elf -l printf.lst  printf1.asm
; Link:		gcc -o printf1  printf1.o
; Run:		printf1
; Output:	a=5, eax=7

; Equivalent C code
; /* printf1.c  print an int and an expression */
; #include 
; int main()
; {
;   int a=5;
;   printf("a=%d, eax=%d\n", a, a+2);
;   return 0;
; }

; Declare some external functions
;
        extern	printf		; the C function, to be called

        SECTION .data		; Data section, initialized variables

	a:	dd	5		; int a=5;
fmt:    db "a=%d, eax=%d", 10, 0 ; The printf format, "\n",'0'


        SECTION .text                   ; Code section.

        global main		; the standard gcc entry point
main:				; the program label for the entry point
        push    ebp		; set up stack frame
        mov     ebp,esp

	mov	eax, [a]	; put a from store into register
	add	eax, 2		; a+2
	push	eax		; value of a+2
        push    dword [a]	; value of variable a
        push    dword fmt	; address of ctrl string
        call    printf		; Call C function
        add     esp, 12		; pop stack 3 push times 4 bytes

        mov     esp, ebp	; takedown stack frame
        pop     ebp		; same as "leave" op

	mov	eax,0		;  normal, no error, return value
	ret			; return
	


printf2.asm more types with printf

  The nasm source code is printf2.asm   The result of the assembly is printf2.lst   The equivalent "C" program is printf2.c   Running the program produces output printf2.out   This program demonstrates basic use of "C" library function  printf.
  The equivalent "C" code is shown as comments in the assembly language.

; printf2.asm  use "C" printf on char, string, int, double
; 
; Assemble:	nasm -f elf -l printf2.lst  printf2.asm
; Link:		gcc -o printf2  printf2.o
; Run:		printf2
; Output:	
;Hello world: a string of length 7 1234567 6789ABCD 5.327000e-30 -1.234568E+302
; 
; A similar "C" program
; #include 
; int main()
; {
;   char   char1='a';         /* sample character */
;   char   str1[]="string";   /* sample string */
;   int    int1=1234567;      /* sample integer */
;   int    hex1=0x6789ABCD;   /* sample hexadecimal */
;   float  flt1=5.327e-30;    /* sample float */
;   double flt2=-123.4e300;   /* sample double */
; 
;   printf("Hello world: %c %s %d %X %e %E \n", /* format string for printf */
;          char1, str1, int1, hex1, flt1, flt2);
;   return 0;
; }


        extern printf                   ; the C function to be called

        SECTION .data                   ; Data section

msg:    db "Hello world: %c %s of length %d %d %X %e %E",10,0
					; format string for printf
char1:	db	'a'			; a character 
str1:	db	"string",0	        ; a C string, "string" needs 0
len:	equ	$-str1			; len has value, not an address
inta1:	dd	1234567		        ; integer 1234567
hex1:	dd	0x6789ABCD	        ; hex constant 
flt1:	dd	5.327e-30		; 32-bit floating point
flt2:	dq	-123.456789e300	        ; 64-bit floating point

	SECTION .bss
		
flttmp:	resq 1			        ; 64-bit temporary for printing flt1
	
        SECTION .text                   ; Code section.

        global	main		        ; "C" main program 
main:				        ; label, start of main program
	 
	fld	dword [flt1]	        ; need to convert 32-bit to 64-bit
	fstp	qword [flttmp]          ; floating load makes 80-bit,
	                                ; store as 64-bit
	                                ; push last argument first
	push	dword [flt2+4]	        ; 64 bit floating point (bottom)
	push	dword [flt2]	        ; 64 bit floating point (top)
	push	dword [flttmp+4]        ; 64 bit floating point (bottom)
	push	dword [flttmp]	        ; 64 bit floating point (top)
	push	dword [hex1]	        ; hex constant
	push	dword [inta1]	        ; integer data pass by value
	push	dword len	        ; constant pass by value
	push	dword str1		; "string" pass by reference 
        push    dword [char1]		; 'a'
        push    dword msg		; address of format string
        call    printf			; Call C function
        add     esp, 40			; pop stack 10*4 bytes

        mov     eax, 0			; exit code, 0=normal
        ret				; main returns to operating system


intarith.asm simple integer arithmetic

  The nasm source code is intarith.asm   The result of the assembly is intarith.lst   The equivalent "C" program is intarith.c   Running the program produces output intarith.out   This program demonstrates basic integer arithmetic  add, subtract,
  multiply and divide.
  The equivalent "C" code is shown as comments in the assembly language.

; intarith.asm    show some simple C code and corresponding nasm code
;                 the nasm code is one sample, not unique
;
; compile:	nasm -f elf -l intarith.lst  intarith.asm
; link:		gcc -o intarith  intarith.o
; run:		intarith
;
; the output from running intarith.asm and intarith.c is:	
; c=5  , a=3, b=4, c=5
; c=a+b, a=3, b=4, c=7
; c=a-b, a=3, b=4, c=-1
; c=a*b, a=3, b=4, c=12
; c=c/a, a=3, b=4, c=4
;
;The file  intarith.c  is:
;  /* intarith.c */
;  #include 
;  int main()
;  { 
;    int a=3, b=4, c;
;
;    c=5;
;    printf("%s, a=%d, b=%d, c=%d\n","c=5  ", a, b, c);
;    c=a+b;
;    printf("%s, a=%d, b=%d, c=%d\n","c=a+b", a, b, c);
;    c=a-b;
;    printf("%s, a=%d, b=%d, c=%d\n","c=a-b", a, b, c);
;    c=a*b;
;    printf("%s, a=%d, b=%d, c=%d\n","c=a*b", a, b, c);
;    c=c/a;
;    printf("%s, a=%d, b=%d, c=%d\n","c=c/a", a, b, c);
;    return 0;
; }

        extern printf		; the C function to be called

%macro	pabc 1			; a "simple" print macro
	section .data
.str	db	%1,0		; %1 is first actual in macro call
	section .text
				; push onto stack backwards 
	push	dword [c]	; int c
	push	dword [b]	; int b 
	push	dword [a]	; int a
	push	dword .str 	; users string
        push    dword fmt       ; address of format string
        call    printf          ; Call C function
        add     esp,20          ; pop stack 5*4 bytes
%endmacro
	
	section .data  		; preset constants, writeable
a:	dd	3		; 32-bit variable a initialized to 3
b:	dd	4		; 32-bit variable b initializes to 4
fmt:    db "%s, a=%d, b=%d, c=%d",10,0	; format string for printf
	
	section .bss 		; unitialized space
c:	resd	1		; reserve a 32-bit word

	section .text		; instructions, code segment
	global	 main		; for gcc standard linking
main:				; label
	
lit5:				; c=5;
	mov	eax,5	 	; 5 is a literal constant
	mov	[c],eax		; store into c
	pabc	"c=5  "		; invoke the print macro
	
addb:				; c=a+b;
	mov	eax,[a]	 	; load a
	add	eax,[b]		; add b
	mov	[c],eax		; store into c
	pabc	"c=a+b"		; invoke the print macro
	
subb:				; c=a-b;
	mov	eax,[a]	 	; load a
	sub	eax,[b]		; subtract b
	mov	[c],eax		; store into c
	pabc	"c=a-b"		; invoke the print macro
	
mulb:				; c=a*b;
	mov	eax,[a]	 	; load a (must be eax for multiply)
	imul	dword [b]	; signed integer multiply by b
	mov	[c],eax		; store bottom half of product into c
	pabc	"c=a*b"		; invoke the print macro
	
diva:				; c=c/a;
	mov	eax,[c]	 	; load c
	mov	edx,0		; load upper half of dividend with zero
	idiv	dword [a]	; divide double register edx eax by a
	mov	[c],eax		; store quotient into c
	pabc	"c=c/a"		; invoke the print macro

        mov     eax,0           ; exit code, 0=normal
	ret			; main return to operating system



fltarith.asm simple floating point arithmetic

  The nasm source code is fltarith.asm   The result of the assembly is fltarith.lst   The equivalent "C" program is fltarith.c   Running the program produces output fltarith.out   This program demonstrates basic floating point add, subtract,
  multiply and divide.
  The equivalent "C" code is shown as comments in the assembly language.

; fltarith.asm   show some simple C code and corresponding nasm code
;                the nasm code is one sample, not unique
;
; compile  nasm -f elf -l fltarith.lst  fltarith.asm
; link     gcc -o fltarith  fltarith.o
; run      fltarith
;
; the output from running fltarith and fltarithc is:	
; c=5.0, a=3.000000e+00, b=4.000000e+00, c=5.000000e+00
; c=a+b, a=3.000000e+00, b=4.000000e+00, c=7.000000e+00
; c=a-b, a=3.000000e+00, b=4.000000e+00, c=-1.000000e+00
; c=a*b, a=3.000000e+00, b=4.000000e+00, c=1.200000e+01
; c=c/a, a=3.000000e+00, b=4.000000e+00, c=4.000000e+00
;
;The file  fltarith.c  is:
;  #include 
;  int main()
;  { 
;    double a=3.0, b=4.0, c;
;
;    c=5.0;
;    printf("%s, a=%e, b=%e, c=%e\n","c=5.0", a, b, c);
;    c=a+b;
;    printf("%s, a=%e, b=%e, c=%e\n","c=a+b", a, b, c);
;    c=a-b;
;    printf("%s, a=%e, b=%e, c=%e\n","c=a-b", a, b, c);
;    c=a*b;
;    printf("%s, a=%e, b=%e, c=%e\n","c=a*b", a, b, c);
;    c=c/a;
;    printf("%s, a=%e, b=%e, c=%e\n","c=c/a", a, b, c);
;    return 0;
; }

        extern printf		; the C function to be called

%macro	pabc 1			; a "simple" print macro
	section	.data
.str	db	%1,0		; %1 is macro call first actual parameter
	section .text
				; push onto stack backwards 
	push	dword [c+4]	; double c (bottom)
	push	dword [c]	; double c
	push	dword [b+4]	; double b (bottom)
	push	dword [b]	; double b 
	push	dword [a+4]	; double a (bottom)
	push	dword [a]	; double a
	push	dword .str 	; users string
        push    dword fmt       ; address of format string
        call    printf          ; Call C function
        add     esp,32          ; pop stack 8*4 bytes
%endmacro
	
	section	.data  		; preset constants, writeable
a:	dq	3.333333333	; 64-bit variable a initialized to 3.0
b:	dq	4.444444444	; 64-bit variable b initializes to 4.0
five:	dq	5.0		; constant 5.0
fmt:    db "%s, a=%e, b=%e, c=%e",10,0	; format string for printf
	
	section .bss 		; unitialized space
c:	resq	1		; reserve a 64-bit word

	section .text		; instructions, code segment
	global	main		; for gcc standard linking
main:				; label
	
lit5:				; c=5.0;
	fld	qword [five]	; 5.0 constant
	fstp	qword [c]	; store into c
	pabc	"c=5.0"		; invoke the print macro
	
addb:				; c=a+b;
	fld	qword [a] 	; load a (pushed on flt pt stack, st0)
	fadd	qword [b]	; floating add b (to st0)
	fstp	qword [c]	; store into c (pop flt pt stack)
	pabc	"c=a+b"		; invoke the print macro
	
subb:				; c=a-b;
	fld	qword [a] 	; load a (pushed on flt pt stack, st0)
	fsub	qword [b]	; floating subtract b (to st0)
	fstp	qword [c]	; store into c (pop flt pt stack)
	pabc	"c=a-b"		; invoke the print macro
	
mulb:				; c=a*b;
	fld	qword [a]	; load a (pushed on flt pt stack, st0)
	fmul	qword [b]	; floating multiply by b (to st0)
	fstp	qword [c]	; store product into c (pop flt pt stack)
	pabc	"c=a*b"		; invoke the print macro
	
diva:				; c=c/a;
	fld	qword [c] 	; load c (pushed on flt pt stack, st0)
	fdiv	qword [a]	; floating divide by a (to st0)
	fstp	qword [c]	; store quotient into c (pop flt pt stack)
	pabc	"c=c/a"		; invoke the print macro

        mov     eax,0           ; exit code, 0=normal
	ret			; main returns to operating system




Go to top

Last updated 10/10/03

转载于:https://my.oschina.net/wxwHome/blog/55861

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值