commit 4f9cd4066a8c325d1b30f1bb46dde8cc8b7e437f Author: Tretter Date: Tue Feb 7 20:07:52 2017 +0000 initial checkin from subversion diff --git a/file1/compile b/file1/compile new file mode 100644 index 0000000..1629825 --- /dev/null +++ b/file1/compile @@ -0,0 +1,2 @@ +nasm -f elf -l file1.lst file1.asm +ld -o file1 file1.o diff --git a/file1/file1 b/file1/file1 new file mode 100644 index 0000000..bbf5020 Binary files /dev/null and b/file1/file1 differ diff --git a/file1/file1.asm b/file1/file1.asm new file mode 100644 index 0000000..b7b22da --- /dev/null +++ b/file1/file1.asm @@ -0,0 +1,42 @@ +section .data + hello db 'Hello, world!',10 ; Our dear string + helloLen equ $ - hello ; Length of our dear string + +section .text + global _start + +_start: + pop ebx ; argc (argument count) + pop ebx ; argv[0] (argument 0, the program name) + pop ebx ; The first real arg, a filename + + mov eax,8 ; The syscall number for creat() (we already have the filename in ebx) + mov ecx,00644Q ; Read/write permissions in octal (rw_rw_rw_) + int 80h ; Call the kernel + ; Now we have a file descriptor in eax + + test eax,eax ; Lets make sure the file descriptor is valid + js skipWrite ; If the file descriptor has the sign flag + ; (which means it's less than 0) there was an oops, + ; so skip the writing. Otherwise call the filewrite "procedure" + call fileWrite + +skipWrite: + mov ebx,eax ; If there was an error, save the errno in ebx + mov eax,1 ; Put the exit syscall number in eax + int 80h ; Bail out + +; proc fileWrite - write a string to a file +fileWrite: + mov ebx,eax ; sys_creat returned file descriptor into eax, now move into ebx + mov eax,4 ; sys_write + ; ebx is already set up + mov ecx,hello ; We are putting the ADDRESS of hello in ecx + mov edx,helloLen ; This is the VALUE of helloLen because it's a constant (defined with equ) + int 80h + + mov eax,6 ; sys_close (ebx already contains file descriptor) + int 80h + ret +; endp fileWrite + diff --git a/file1/file1.lst b/file1/file1.lst new file mode 100644 index 0000000..872f258 --- /dev/null +++ b/file1/file1.lst @@ -0,0 +1,43 @@ + 1 section .data + 2 00000000 48656C6C6F2C20776F- hello db 'Hello, world!',10 ; Our dear string + 3 00000009 726C64210A + 4 helloLen equ $ - hello ; Length of our dear string + 5 + 6 section .text + 7 global _start + 8 + 9 _start: + 10 00000000 5B pop ebx ; argc (argument count) + 11 00000001 5B pop ebx ; argv[0] (argument 0, the program name) + 12 00000002 5B pop ebx ; The first real arg, a filename + 13 + 14 00000003 B808000000 mov eax,8 ; The syscall number for creat() (we already have the filename in ebx) + 15 00000008 B9A4010000 mov ecx,00644Q ; Read/write permissions in octal (rw_rw_rw_) + 16 0000000D CD80 int 80h ; Call the kernel + 17 ; Now we have a file descriptor in eax + 18 + 19 0000000F 85C0 test eax,eax ; Lets make sure the file descriptor is valid + 20 00000011 7805 js skipWrite ; If the file descriptor has the sign flag + 21 ; (which means it's less than 0) there was an oops, + 22 ; so skip the writing. Otherwise call the filewrite "procedure" + 23 00000013 E809000000 call fileWrite + 24 + 25 skipWrite: + 26 00000018 89C3 mov ebx,eax ; If there was an error, save the errno in ebx + 27 0000001A B801000000 mov eax,1 ; Put the exit syscall number in eax + 28 0000001F CD80 int 80h ; Bail out + 29 + 30 ; proc fileWrite - write a string to a file + 31 fileWrite: + 32 00000021 89C3 mov ebx,eax ; sys_creat returned file descriptor into eax, now move into ebx + 33 00000023 B804000000 mov eax,4 ; sys_write + 34 ; ebx is already set up + 35 00000028 B9[00000000] mov ecx,hello ; We are putting the ADDRESS of hello in ecx + 36 0000002D BA0E000000 mov edx,helloLen ; This is the VALUE of helloLen because it's a constant (defined with equ) + 37 00000032 CD80 int 80h + 38 + 39 00000034 B806000000 mov eax,6 ; sys_close (ebx already contains file descriptor) + 40 00000039 CD80 int 80h + 41 0000003B C3 ret + 42 ; endp fileWrite + 43 diff --git a/floatArithmetics/compile b/floatArithmetics/compile new file mode 100644 index 0000000..51a9c7a --- /dev/null +++ b/floatArithmetics/compile @@ -0,0 +1,2 @@ +nasm -f elf -l fltarith.lst fltarith.asm +gcc -o fltarith fltarith.o diff --git a/floatArithmetics/fltarith b/floatArithmetics/fltarith new file mode 100644 index 0000000..11fa436 Binary files /dev/null and b/floatArithmetics/fltarith differ diff --git a/floatArithmetics/fltarith.asm b/floatArithmetics/fltarith.asm new file mode 100644 index 0000000..c613229 --- /dev/null +++ b/floatArithmetics/fltarith.asm @@ -0,0 +1,98 @@ +; 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 + + diff --git a/hello/compile b/hello/compile new file mode 100644 index 0000000..467865f --- /dev/null +++ b/hello/compile @@ -0,0 +1,2 @@ +nasm -f elf -l hello.lst hello.asm +gcc -o hello hello.o diff --git a/hello/hello b/hello/hello new file mode 100644 index 0000000..3d9bd33 Binary files /dev/null and b/hello/hello differ diff --git a/hello/hello.asm b/hello/hello.asm new file mode 100644 index 0000000..3ef9623 --- /dev/null +++ b/hello/hello.asm @@ -0,0 +1,27 @@ +; 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 + + diff --git a/integerarithmetics/compile b/integerarithmetics/compile new file mode 100644 index 0000000..22c3839 --- /dev/null +++ b/integerarithmetics/compile @@ -0,0 +1,2 @@ +nasm -f elf -l intarith.lst intarith.asm +gcc -o intarith intarith.o diff --git a/integerarithmetics/intarith b/integerarithmetics/intarith new file mode 100644 index 0000000..64ee58f Binary files /dev/null and b/integerarithmetics/intarith differ diff --git a/integerarithmetics/intarith.asm b/integerarithmetics/intarith.asm new file mode 100644 index 0000000..e3209ec --- /dev/null +++ b/integerarithmetics/intarith.asm @@ -0,0 +1,95 @@ +; 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 + diff --git a/printf1/compile b/printf1/compile new file mode 100644 index 0000000..0468739 --- /dev/null +++ b/printf1/compile @@ -0,0 +1,2 @@ +nasm -f elf -l printf1.lst printf1.asm +gcc -o printf1 printf1.o diff --git a/printf1/printf1 b/printf1/printf1 new file mode 100644 index 0000000..ba72dee Binary files /dev/null and b/printf1/printf1 differ diff --git a/printf1/printf1.asm b/printf1/printf1.asm new file mode 100644 index 0000000..baac75b --- /dev/null +++ b/printf1/printf1.asm @@ -0,0 +1,47 @@ +; 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 + diff --git a/printf2/compile b/printf2/compile new file mode 100644 index 0000000..3db7b94 --- /dev/null +++ b/printf2/compile @@ -0,0 +1,2 @@ +nasm -f elf -l printf2.lst printf2.asm +gcc -o printf2 printf2.o diff --git a/printf2/printf2 b/printf2/printf2 new file mode 100644 index 0000000..e55f2c8 Binary files /dev/null and b/printf2/printf2 differ diff --git a/printf2/printf2.asm b/printf2/printf2.asm new file mode 100644 index 0000000..7979337 --- /dev/null +++ b/printf2/printf2.asm @@ -0,0 +1,67 @@ +; 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