add files
+1294 · 16 files changed
-
fasm1.asm+61 −0 -
fasm2.asm+60 −0 -
fasm3.asm+66 −0 -
fasm4-bugfix.asm+67 −0 -
fasm5.asm+33 −0 -
fasm6.asm+35 −0 -
fasm7.asm+31 −0 -
fasm8.asm+79 −0 -
fasm8a.asm+84 −0 -
fasm8b.asm+85 −0 -
fasm8c.asm+100 −0 -
fasm8d.asm+104 −0 -
fasm8e.asm+104 −0 -
fasm8f.asm+134 −0 -
fasm8g.asm+112 −0 -
fasm8h.asm+139 −0
@@ -0,0 +1,61 @@ +format ELF64 executable 3 +; v.02 create function outside of main and +; calculate the length of the string + +segment readable executable + +entry main + +main: + lea rdi, [msg] ; load effective address of msg into rdi - + ; computes the effective address in memory (offset within a segment) + ; of a source operand and places it in gp register + ; useful for initializing RSI,ESI,RDI,EDI before the exection of + ; string instructions + call .strlen ; call strlne function + mov rdx, rax ; moving 'rax' value to 'rdx' + mov rsi, rdi ; moving 'rdi' value to 'rsi' + mov rdi, 1 ; stdout + mov rax, 1 ; syswrite + syscall + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, 60 ; use sys.exit + syscall ; call OS + +.strlen: + push rdi ; push registers to stack + push rcx ; saving these values + ; after function return leave as intiial state + sub rcx, rcx ; set rcx to 0 + mov rcx, -1 ; negative one to rcx + sub al, al + cld ; clear direction flags - + ; Clearing the DF flag causes the string instructions to auto-increment + ; (process strings from low addresses to high addresses). + repne scasb ; scans through a strings and compares the characters of string to + ; whatever is in 'al' scasb. Look at string char by char and compare to al and reach zero + ; repeat if not equal will exit the loop + ; The SCAS instruction subtracts the destination string element from the contents of the EAX, AX, or AL register + ; (depending on operand length) and updates the status flags according to the results. The string element and + ; register contents are not modified. The following “short forms” of the SCAS instruction specify the operand length: + ; SCASB (scan byte string), SCASW (scan word string), and SCASD (scan doubleword string). + ; When used in string instructions, the ESI and EDI registers + ; are automatically incremented or decremented after each iteration of an instruction to point to the next element (byte, + ; word, or doubleword) in the string. String operations can thus begin at higher addresses and work toward lower ones, + ; or they can begin at lower addresses and work toward higher ones. The DF flag in the EFLAGS register controls + ; whether the registers are incremented (DF = 0) or decremented (DF = 1). The STD and CLD instructions set and + ; clear this flag, respectively. + neg rcx ; negate rcx so it will be a positive number + sub rcx,1 ; our string ends with a zero so we need to sub one + mov rax,rcx ; we now have the string length and we should return the value of the + ; string length now in rcx into rax register. Returning functions to + ; rax is best practice. + pop rcx ; restore the registers to initial state + pop rdi ; restore original rdi value + ret ; return the function + +segment readable writable ; this is where we put our data + + msg db 'Hello World!', 0xA, 0 ; we call it message and declare bytes and say + ; 'Hello World'. 10 for newline character and end with 0 + ; H e l l o\ W o r l d ! 0xA 0 - 14 @@ -0,0 +1,60 @@ +format ELF64 executable 3 +; v.02 create function outside of main and +; calculate the length of the string + +segment readable executable + +entry main + +main: + lea rdi, [msg] ; load effective address of msg into rdi - + ; computes the effective address in memory (offset within a segment) + ; of a source operand and places it in gp register + ; useful for initializing RSI,ESI,RDI,EDI before the exection of + ; string instructions + call .strlen ; call strlne function + mov rdx, rax ; moving 'rax' value to 'rdx' + mov rsi, rdi ; moving 'rdi' value to 'rsi' + mov rdi, 1 ; stdout + mov rax, 1 ; syswrite + syscall + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, 60 ; use sys.exit + syscall ; call OS + +.strlen: + push rdi ; push registers to stack + push rcx ; saving these values + ; after function return leave as intiial state + sub rcx, rcx ; set rcx to 0 + mov rcx, -1 ; negative one to rcx + cld ; clear direction flags - + ; Clearing the DF flag causes the string instructions to auto-increment + ; (process strings from low addresses to high addresses). + repne scasb ; scans through a strings and compares the characters of string to + ; whatever is in 'al' scasb. Look at string char by char and compare to al and reach zero + ; repeat if not equal will exit the loop + ; The SCAS instruction subtracts the destination string element from the contents of the EAX, AX, or AL register + ; (depending on operand length) and updates the status flags according to the results. The string element and + ; register contents are not modified. The following “short forms” of the SCAS instruction specify the operand length: + ; SCASB (scan byte string), SCASW (scan word string), and SCASD (scan doubleword string). + ; When used in string instructions, the ESI and EDI registers + ; are automatically incremented or decremented after each iteration of an instruction to point to the next element (byte, + ; word, or doubleword) in the string. String operations can thus begin at higher addresses and work toward lower ones, + ; or they can begin at lower addresses and work toward higher ones. The DF flag in the EFLAGS register controls + ; whether the registers are incremented (DF = 0) or decremented (DF = 1). The STD and CLD instructions set and + ; clear this flag, respectively. + neg rcx ; negate rcx so it will be a positive number + sub rcx,1 ; our string ends with a zero so we need to sub one + mov rax,rcx ; we now have the string length and we should return the value of the + ; string length now in rcx into rax register. Returning functions to + ; rax is best practice. + pop rcx ; restore the registers to initial state + pop rdi ; restore original rdi value + ret ; return the function + +segment readable writable ; this is where we put our data + + msg db 'Hello World!', 0xA, 0 ; we call it message and declare bytes and say + ; 'Hello World'. 10 for newline character and end with 0 + ; H e l l o\ W o r l d ! 0xA 0 - 14 @@ -0,0 +1,66 @@ +format ELF64 executable 3 +; v.03 make also a print function to free up main +; v.02 create function outside of main and +; calculate the length of the string + +segment readable executable + +entry main + +main: + lea rdi, [msg] ; load effective address of msg into rdi - + ; computes the effective address in memory (offset within a segment) + ; of a source operand and places it in gp register + ; useful for initializing RSI,ESI,RDI,EDI before the exection of + ; string instructions + call .strlen ; call strlne function + call .print ; we call the print function + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, 60 ; use sys.exit + syscall ; call OS + +.strlen: + push rdi ; push registers to stack + push rcx ; saving these values + ; after function return leave as intiial state + sub rcx, rcx ; set rcx to 0 + mov rcx, -1 ; negative one to rcx + cld ; clear direction flags - + ; Clearing the DF flag causes the string instructions to auto-increment + ; (process strings from low addresses to high addresses). + repne scasb ; scans through a strings and compares the characters of string to + ; whatever is in 'al' scasb. Look at string char by char and compare to al and reach zero + ; repeat if not equal will exit the loop + ; The SCAS instruction subtracts the destination string element from the contents of the EAX, AX, or AL register + ; (depending on operand length) and updates the status flags according to the results. The string element and + ; register contents are not modified. The following “short forms” of the SCAS instruction specify the operand length: + ; SCASB (scan byte string), SCASW (scan word string), and SCASD (scan doubleword string). + ; When used in string instructions, the ESI and EDI registers + ; are automatically incremented or decremented after each iteration of an instruction to point to the next element (byte, + ; word, or doubleword) in the string. String operations can thus begin at higher addresses and work toward lower ones, + ; or they can begin at lower addresses and work toward higher ones. The DF flag in the EFLAGS register controls + ; whether the registers are incremented (DF = 0) or decremented (DF = 1). The STD and CLD instructions set and + ; clear this flag, respectively. + neg rcx ; negate rcx so it will be a positive number + sub rcx,1 ; our string ends with a zero so we need to sub one + mov rax,rcx ; we now have the string length and we should return the value of the + ; string length now in rcx into rax register. Returning functions to + ; rax is best practice. + pop rcx ; restore the registers to initial state + pop rdi ; restore original rdi value + ret ; return the function + +.print: + call .strlen ; will have string length in rax + mov rdx, rax ; so this will be copied to rdx + mov rsi, rdi ; and also copy the rdi into rsi + mov rdi, 1 ; stdout - argument + mov rax, 1 ; syswrite - kernel function + syscall ; call linux os kernel + ret ; return to next instruction - xor rdi, rdi + +segment readable writable ; this is where we put our data + + msg db 'Hello World!', 0xA, 0 ; we call it message and declare bytes and say + ; 'Hello World'. 10 for newline character and end with 0 + ; H e l l o\ W o r l d ! 0xA 0 - 14 @@ -0,0 +1,67 @@ +format ELF64 executable 3 +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + +segment readable executable + +entry main + +main: + lea rdi, [msg] ; load effective address of msg into rdi - + ; computes the effective address in memory (offset within a segment) + ; of a source operand and places it in gp register + ; useful for initializing RSI,ESI,RDI,EDI before the exection of + ; string instructions + call .print ; we call the print function + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, 60 ; use sys.exit + syscall ; call OS + +.strlen: + push rdi ; push registers to stack + push rcx ; saving these values + ; after function return leave as intiial state + sub rcx, rcx ; set rcx to 0 + mov rcx, -1 ; negative one to rcx + sub al, al + cld ; clear direction flags - + ; Clearing the DF flag causes the string instructions to auto-increment + ; (process strings from low addresses to high addresses). + repne scasb ; scans through a strings and compares the characters of string to + ; whatever is in 'al' scasb. Look at string char by char and compare to al and reach zero + ; repeat if not equal will exit the loop + ; The SCAS instruction subtracts the destination string element from the contents of the EAX, AX, or AL register + ; (depending on operand length) and updates the status flags according to the results. The string element and + ; register contents are not modified. The following “short forms” of the SCAS instruction specify the operand length: + ; SCASB (scan byte string), SCASW (scan word string), and SCASD (scan doubleword string). + ; When used in string instructions, the ESI and EDI registers + ; are automatically incremented or decremented after each iteration of an instruction to point to the next element (byte, + ; word, or doubleword) in the string. String operations can thus begin at higher addresses and work toward lower ones, + ; or they can begin at lower addresses and work toward higher ones. The DF flag in the EFLAGS register controls + ; whether the registers are incremented (DF = 0) or decremented (DF = 1). The STD and CLD instructions set and + ; clear this flag, respectively. + neg rcx ; negate rcx so it will be a positive number + sub rcx,1 ; our string ends with a zero so we need to sub one + mov rax,rcx ; we now have the string length and we should return the value of the + ; string length now in rcx into rax register. Returning functions to + ; rax is best practice. + pop rcx ; restore the registers to initial state + pop rdi ; restore original rdi value + ret ; return the function + +.print: + call .strlen ; will have string length in rax + mov rdx, rax ; so this will be copied to rdx + mov rsi, rdi ; and also copy the rdi into rsi + mov rdi, 1 ; stdout - argument + mov rax, 1 ; syswrite - kernel function + syscall ; call linux os kernel + ret ; return to next instruction - xor rdi, rdi + +segment readable writable ; this is where we put our data + + msg db 'Hello World!', 0xA, 0 ; we call it message and declare bytes and say + ; 'Hello World'. 10 for newline character and end with 0 + ; H e l l o\ W o r l d ! 0xA 0 - 14 @@ -0,0 +1,33 @@ +format ELF64 executable 3 +; v.05 include files - move functions to separate file +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + +segment readable executable + +entry main + +include 'io.inc' ; the name of the file to be included + +main: + lea rdi, [msg] ; load effective address of msg into rdi - + ; computes the effective address in memory (offset within a segment) + ; of a source operand and places it in gp register + ; useful for initializing RSI,ESI,RDI,EDI before the exection of + ; string instructions + call print ; we call the print function + lea rdi, [msg2] ; testing with another message + call print ; printing it + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, 60 ; use sys.exit + syscall ; call OS + +segment readable writable ; this is where we put our data + + msg db 'Hello World!', 0xA, 0 ; we call it message and declare bytes and say + ; 'Hello World'. 10 for newline character and end with 0 + ; H e l l o\ W o r l d ! 0xA 0 - 14 + + msg2 db 'This is another string!', 0xA, 0 @@ -0,0 +1,35 @@ +format ELF64 executable 3 +; v.06 use syscalls names from kernel instead of numerics +; v.05 include files - move functions to separate file +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + +segment readable executable + +entry main + +include 'unistd64.inc' +include 'io.inc' ; the name of the file to be included + +main: + lea rdi, [msg] ; load effective address of msg into rdi - + ; computes the effective address in memory (offset within a segment) + ; of a source operand and places it in gp register + ; useful for initializing RSI,ESI,RDI,EDI before the exection of + ; string instructions + call print ; we call the print function + lea rdi, [msg2] ; testing with another message + call print ; printing it + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, sys_exit ; use sys.exit + syscall ; call OS + +segment readable writable ; this is where we put our data + + msg db 'Hello World!', 0xA, 0 ; we call it message and declare bytes and say + ; 'Hello World'. 10 for newline character and end with 0 + ; H e l l o\ W o r l d ! 0xA 0 - 14 + + msg2 db 'This is another string!', 0xA, 0 @@ -0,0 +1,31 @@ +format ELF64 executable 3 +; v.07 - read from stdin +; v.06 use syscalls names from kernel instead of numerics +; v.05 include files - move functions to separate file +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + +segment readable executable + +entry main + +include 'unistd64.inc' +include 'io.inc' ; the name of the file to be included + +main: + lea rdi, [prompt] + call print + lea rsi, [buf] + mov rdi, 64 + call read + mov rdi, rsi ; copy string we read to rdi + call print + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, sys_exit ; use sys.exit + syscall ; call OS + +segment readable writable ; this is where we put our data + prompt db 'Please type your name: ',0 + buf rb 64 @@ -0,0 +1,79 @@ +format ELF64 executable 3 +; -r1 - remove strlen - string can be arbitrary, max value is 1024 +; v.08 factoriadic; change mov rdi 04 to rdi strlen +; v.07 - read from stdin +; v.06 use syscalls names from kernel instead of numerics +; v.05 include files - move functions to separate file +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + + +segment readable executable + +entry main + +include 'unistd64.inc' +include 'io.inc' ; the name of the file to be included + +main: + lea rdi, [prompt] ; load effective address of prompt + call print ; print to screen the prompt call 0x4000ce + + lea rsi, [buf] ; load effective address of buffer + mov rdi, 1024 ; 1024 number copy to rdi + call read ; read + call convert ; call 0x400136 + + mov rdi, rsi ; copy string we read to rdi + call print ; output to standard out + + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, sys_exit ; use sys.exit + syscall ; call OS + + +; accept string and convert each digit to base 10 +; takes as a parameter rsi which points to string +; mov rdi, rsi ; copy string we read to rdi + +convert: + sub al, al ; zero out the lower bytes (rightmost byte) + xor rcx,rcx +; lea r8, [digitcnt] + lea rbx, [numberbuf] + call loopString + ret + +loopString: + lodsb ; load byte string - a character is a byte - in ascii + ; and we entered ascii text into stdin + ; loadsb will load the source element - the number - identified by the + ; ESI/RSI register into the EAX/RAX register - for doubleword, AX for word, + ; AL for byte string (lodsb,lodsw,lodsd) + ; in this case we want just a single byte at a time to load into RAX + cmp al, 0xa ; compare to newlinecode + je loopString ; + or al, al ; is the string that we read null terminated ? -has al reached the 0 marker + ; for null terminated strings? + jz addctr ; je 0x40014f jump to addctr address + and al, 0xf ; keep binary value of numerical digit + add rdi,rax ; store + add [rbx], al + inc rbx +; inc rdi + inc rcx + jmp loopString ; return to beginning and do the same taks + + + +addctr: + mov [digitcnt], rcx ;add to counter how many digits + ret + +segment readable writable ; this is where we put our data + prompt db 'Please input number to list its factoriadic values (1024 digits max): ' ,0 + buf rb 1024 + digitcnt dq ? + numberbuf db 1024 dup(?) @@ -0,0 +1,84 @@ +format ELF64 executable 3 +; -r1 - remove strlen - string can be arbitrary, max value is 1024 +; v.08 factoriadic; change mov rdi 04 to rdi strlen +; v.07 - read from stdin +; v.06 use syscalls names from kernel instead of numerics +; v.05 include files - move functions to separate file +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + + +segment readable executable + +entry main + +include 'unistd64.inc' +include 'io.inc' ; the name of the file to be included + +main: + lea rdi, [prompt] ; load effective address of prompt + call print ; print to screen the prompt call 0x4000ce + + lea rsi, [buf] ; load effective address of buffer + mov rdi, 1024 ; 1024 number copy to rdi + call read ; read + call convert ; call 0x400136 + + mov rdi, rsi ; copy string we read to rdi + call print ; output to standard out + + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, sys_exit ; use sys.exit + syscall ; call OS + + +; accept string and convert each digit to base 10 +; takes as a parameter rsi which points to string +; mov rdi, rsi ; copy string we read to rdi + +convert: +; lea r8, [digitcnt] +; lea r8, [numberbuf] + xor rbx,rbx ; clear r8 + call loopString + ret + +loopString: + lodsb ; load byte string - a character is a byte - in ascii + ; and we entered ascii text into stdin + ; loadsb will load the source element - the number - identified by the + ; ESI/RSI register into the EAX/RAX register - for doubleword, AX for word, + ; AL for byte string (lodsb,lodsw,lodsd) + ; in this case we want just a single byte at a time to load into RAX + ; movzx rax, byte[rsi] + cmp al, 0xa ; compare to newlinecode + je addctr +; je loopString ; +; or al, al ; is the string that we read null terminated ? -has al reached the 0 marker + ; for null terminated strings? +; jz addctr ; je 0x40014f jump to addctr address +; and al, 0xf ; keep binary value of numerical digit + and al, 0xf + imul rbx,10 + add rbx,rax ; store + ; add [rbx], r8b +; inc rbx +; mov rax, rbx + xor ax, ax ; zero out the lower bytes (rightmost byte) +; inc rdi +; inc rcx + jmp loopString ; return to beginning and do the same taks + + + +addctr: + mov [digitcnt], rcx ;add to counter how many digits + ret + +segment readable writable ; this is where we put our data + prompt db 'Please input number to list its factoriadic values (1024 digits max): ' ,0 + buf rb 1024 + digitcnt dq ? + numberbuf db 1024 dup(?) @@ -0,0 +1,85 @@ +format ELF64 executable 3 +; -r1 - remove strlen - string can be arbitrary, max value is 1024 +; v.08 factoriadic; change mov rdi 04 to rdi strlen +; v.07 - read from stdin +; v.06 use syscalls names from kernel instead of numerics +; v.05 include files - move functions to separate file +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + + +segment readable executable + +entry main + +include 'unistd64.inc' +include 'io.inc' ; the name of the file to be included + +main: + lea rdi, [prompt] ; load effective address of prompt + call print ; print to screen the prompt call 0x4000ce + + lea rsi, [buf] ; load effective address of buffer + mov rdi, 1024 ; 1024 number copy to rdi + call read ; read + call convert ; call 0x400136 + + mov rdi, rsi ; copy string we read to rdi + call print ; output to standard out + + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, sys_exit ; use sys.exit + syscall ; call OS + + +; accept string and convert each digit to base 10 +; takes as a parameter rsi which points to string +; mov rdi, rsi ; copy string we read to rdi + +convert: +; lea r8, [digitcnt] +; lea r8, [numberbuf] + xor rbx,rbx ; clear r8 + call loopString + ret + +loopString: + lodsb ; load byte string - a character is a byte - in ascii + ; and we entered ascii text into stdin + ; loadsb will load the source element - the number - identified by the + ; ESI/RSI register into the EAX/RAX register - for doubleword, AX for word, + ; AL for byte string (lodsb,lodsw,lodsd) + ; in this case we want just a single byte at a time to load into RAX + ; movzx rax, byte[rsi] + cmp al, 0xa ; compare to newlinecode +; je loopString ; +; or al, al ; is the string that we read null terminated ? -has al reached the 0 marker + ; for null terminated strings? +; jz addctr ; je 0x40014f jump to addctr address +; and al, 0xf ; keep binary value of numerical digit + and al, 0xf + imul rbx,10 + add rbx,rax ; store + cmovc [numberbuf] + ; add [rbx], r8b +; inc rbx +; mov rax, rbx + xor ax, ax ; zero out the lower bytes (rightmost byte) +; inc rdi +; inc rcx + jmp loopString ; return to beginning and do the same taks + + + +addctr: + mov [digitcnt], rcx ;add to counter how many digits + ret + +segment readable writable ; this is where we put our data + prompt db 'Please input number to list its factoriadic values (1024 digits max): ' ,0 + buf rb 1024 + digitcnt dq ? + numberbuf dq 1024 dup(?) + error @@ -0,0 +1,100 @@ +format ELF64 executable 3 +; -r2 - add store it to store a larger than 8 byte - 64 bit value from register onto stack +; the imul and add are found from the net +; -r1 - remove strlen - string can be arbitrary, max value is 1024 +; v.08 factoriadic; change mov rdi 04 to rdi strlen +; v.07 - read from stdin +; v.06 use syscalls names from kernel instead of numerics +; v.05 include files - move functions to separate file +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + + +segment readable executable + +entry main + +include 'unistd64.inc' +include 'io.inc' ; the name of the file to be included + +main: + lea rdi, [prompt] ; load effective address of prompt + call print ; print to screen the prompt call 0x4000ce + + lea rsi, [buf] ; load effective address of buffer + mov rdi, 1024 ; 1024 number copy to rdi + call read ; read + call convert ; call 0x400136 + + mov rdi, rsi ; copy string we read to rdi + call print ; output to standard out + + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, sys_exit ; use sys.exit + syscall ; call OS + + +; accept string and convert each digit to base 10 +; takes as a parameter rsi which points to string +; mov rdi, rsi ; copy string we read to rdi + +convert: +; lea r8, [digitcnt] +; lea r8, [numberbuf] + xor rbx,rbx ; clear r8 + call loopString + ret + +loopString: + lodsb ; load byte string - a character is a byte - in ascii + ; and we entered ascii text into stdin + ; loadsb will load the source element - the number - identified by the + ; ESI/RSI register into the EAX/RAX register - for doubleword, AX for word, + ; AL for byte string (lodsb,lodsw,lodsd) + ; in this case we want just a single byte at a time to load into RAX + ; movzx rax, byte[rsi] + cmp al, 0xa ; compare to newlinecode + je addctr ; in case this compare is equal jumpt to condition addcr +; or al, al ; is the string that we read null terminated ? -has al reached the 0 marker + ; for null terminated strings? +; jz addctr ; je 0x40014f jump to addctr address +; and al, 0xf ; keep binary value of numerical digit + and al, 0xf + imul rbx,10 + jc storeit + add rbx,rax ; store + ; add [rbx], r8b +; inc rbx +; mov rax, rbx + xor ax, ax ; zero out the lower bytes (rightmost byte) +; inc rdi +; inc rcx + jmp loopString ; return to beginning and do the same taks + + + +addctr: + mov [digitcnt], rcx ;add to counter how many digits + ret + +storeit: ; store result onto stack when carry bit is on + mov rbp,rsp ; wanna save that stack pointer so we don't get lost + sub rsp,64 ; and move down the stack 64 bytes (8*rbx) + stc ; this will clear the carry flagg and cmovc will not run - turn it on + cmovc r10,rbx ; cmovc will run if carry flag is set and copy the rbx to r10 - + ; should be another gp register ? + push r10 ; then push to stack that is now 8 bytes down + xor r10,r10 ; cleanup on r10 + xor rbx,rbx ; cleanup on rbx + mov rsp,rbp ; point the stack pointer back from the base pointer to resume with + ; add rbx,rax + mov rbx,rax ; copy the rax register - this was holding a value that is neded + call loopString ; call the function - loopString - hmm + +segment readable writable ; this is where we put our data + prompt db 'Please input number to list its factoriadic values (1024 digits max): ' ,0 + buf rb 1024 + digitcnt dq ? + numberbuf dq 1024 dup(?) @@ -0,0 +1,104 @@ +format ELF64 executable 3 +; -r4 extra 9 +; +; 0x00000000000f423f 999 999 +8 bytes +; 0x8ac7230489e7fff6 9 999 999 999 999 999 990 STACK +; input: 9 999 999 999 999 999 999 999 99 +; -r3 - xor r10, xor rbx - removed on stoerit - they will be overwritten - no needf for theese. +; -r2 - add store it to store a larger than 8 byte - 64 bit value from register onto stack +; the imul and add are found from the net +; -r1 - remove strlen - string can be arbitrary, max value is 1024 +; v.08 factoriadic; change mov rdi 04 to rdi strlen +; v.07 - read from stdin +; v.06 use syscalls names from kernel instead of numerics +; v.05 include files - move functions to separate file +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + + +segment readable executable + +entry main + +include 'unistd64.inc' +include 'io.inc' ; the name of the file to be included + +main: + lea rdi, [prompt] ; load effective address of prompt + call print ; print to screen the prompt call 0x4000ce + + lea rsi, [buf] ; load effective address of buffer + mov rdi, 1024 ; 1024 number copy to rdi + call read ; read + call convert ; call 0x400136 + + mov rdi, rsi ; copy string we read to rdi + call print ; output to standard out + + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, sys_exit ; use sys.exit + syscall ; call OS + + +; accept string and convert each digit to base 10 +; takes as a parameter rsi which points to string +; mov rdi, rsi ; copy string we read to rdi + +convert: +; lea r8, [digitcnt] +; lea r8, [numberbuf] + xor rbx,rbx ; clear r8 + call loopString + ret + +loopString: ; 0x40013F + lodsb ; load byte string - a character is a byte - in ascii + ; and we entered ascii text into stdin + ; loadsb will load the source element - the number - identified by the + ; ESI/RSI register into the EAX/RAX register - for doubleword, AX for word, + ; AL for byte string (lodsb,lodsw,lodsd) + ; in this case we want just a single byte at a time to load into RAX + ; movzx rax, byte[rsi] + cmp al, 0xa ; compare to newlinecode + je storeit ; in case this compare is equal jumpt to condition addcr + or al, al ; is the string that we read null terminated ? -has al reached the 0 marker + ; for null terminated strings? + jz addctr ; je 0x40014f jump to addctr address + and al, 0xf ; keep binary value of numerical digit + imul rbx,10 + jc storeit + add rbx,rax ; store + ; add [dbx], r8b +; inc rbx +; mov rax, rbx + xor ax, ax ; zero out the lower bytes (rightmost byte) +; inc rdi +; inc rcx + jmp loopString ; return to beginning and do the same taks + + + +addctr: + mov [digitcnt], rcx ;add to counter how many digits + ret + +storeit: ; store result onto stack when carry bit is on + mov rbp,rsp ; wanna save that stack pointer so we don't get lost + sub rsp,64 ; and move down the stack 64 bytes (8*rbx) + stc ; this will clear the carry flagg and cmovc will not run - turn it on + cmovc r10,rbx ; cmovc will run if carry flag is set and copy the rbx to r10 - + ; should be another gp register ? + push r10 ; then push to stack that is now 8 bytes down + mov rsp,rbp ; point the stack pointer back from the base pointer to resume with + ; add rbx,rax +; mov rbx,rax ; copy the rax register - this was holding a value that is neded rax + ; will not clear but will be cleared by next lodsb instruction + call loopString ; call the function - loopString - hmm ; + +segment readable writable ; this is where we put our data + prompt db 'Please input number to list its factoriadic values (1024 digits max): ' ,0 + buf rb 1024 + digitcnt dq ? + numberbuf dq 1024 dup(?) @@ -0,0 +1,104 @@ +format ELF64 executable 3 +; -r4 +; 0xD3C21BCECCEDA0FFFFFF +; 0x00000000000f423f 9 999 99 +8 bytes +; 0x8ac7230489e7fff6 9 999 999 999 999 999 990 STACK +; input: 9 999 999 999 999 999 999 999 99 +; -r3 - xor r10, xor rbx - removed on stoerit - they will be overwritten - no needf for theese. +; -r2 - add store it to store a larger than 8 byte - 64 bit value from register onto stack +; the imul and add are found from the net +; -r1 - remove strlen - string can be arbitrary, max value is 1024 +; v.08 factoriadic; change mov rdi 04 to rdi strlen +; v.07 - read from stdin +; v.06 use syscalls names from kernel instead of numerics +; v.05 include files - move functions to separate file +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + + +segment readable executable + +entry main + +include 'unistd64.inc' +include 'io.inc' ; the name of the file to be included + +main: + lea rdi, [prompt] ; load effective address of prompt + call print ; print to screen the prompt call 0x4000ce + + lea rsi, [buf] ; load effective address of buffer + mov rdi, 1024 ; 1024 number copy to rdi + call read ; read + call convert ; call 0x400136 + + mov rdi, rsi ; copy string we read to rdi + call print ; output to standard out + + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, sys_exit ; use sys.exit + syscall ; call OS + + +; accept string and convert each digit to base 10 +; takes as a parameter rsi which points to string +; mov rdi, rsi ; copy string we read to rdi + +convert: +; lea r8, [digitcnt] +; lea r8, [numberbuf] + xor rbx,rbx ; clear r8 + call loopString + ret + +loopString: ; 0x40013F + lodsb ; load byte string - a character is a byte - in ascii + ; and we entered ascii text into stdin + ; loadsb will load the source element - the number - identified by the + ; ESI/RSI register into the EAX/RAX register - for doubleword, AX for word, + ; AL for byte string (lodsb,lodsw,lodsd) + ; in this case we want just a single byte at a time to load into RAX + ; movzx rax, byte[rsi] + cmp al, 0xa ; compare to newlinecode + je storeit ; in case this compare is equal jumpt to condition addcr + or al, al ; is the string that we read null terminated ? -has al reached the 0 marker + ; for null terminated strings? + jz addctr ; je 0x40014f jump to addctr address + and al, 0xf ; keep binary value of numerical digit + imul rbx,10 + jc storeit + add rbx,rax ; store + ; add [dbx], r8b +; inc rbx +; mov rax, rbx + xor ax, ax ; zero out the lower bytes (rightmost byte) +; inc rdi +; inc rcx + jmp loopString ; return to beginning and do the same taks + + + +addctr: + mov [digitcnt], rcx ;add to counter how many digits -- ignored for now + ret + +storeit: ; store result onto stack when carry bit is on + mov rbp,rsp ; wanna save that stack pointer so we don't get lost + sub rsp,64 ; and move down the stack 64 bytes (8*rbx) + stc ; this will clear the carry flagg and cmovc will not run - turn it on + cmovc r10,rbx ; cmovc will run if carry flag is set and copy the rbx to r10 - + ; should be another gp register ? + push r10 ; then push to stack that is now 8 bytes down + mov rsp,rbp ; point the stack pointer back from the base pointer to resume with + ; add rbx,rax + mov rbx,rax ; copy the rax register - this was holding a value that is neded rax + ; will not clear but will be cleared by next lodsb instruction + call loopString ; call the function - loopString - going back to lodsb + +segment readable writable ; this is where we put our data + prompt db 'Please input number to list its factoriadic values (1024 digits max): ' ,0 + buf rb 1024 + digitcnt dq ? + numberbuf dq 1024 dup(?) @@ -0,0 +1,134 @@ +format ELF64 executable 3 +; -r5 - move each value to the datasection not suppose to be in stack +; -r4 +; 0xD3C21BCECCEDA0FFFFFF +; 0x00000000000f423f 9 999 99 +8 bytes +; 0x8ac7230489e7fff6 9 999 999 999 999 999 990 STACK +; input: 9 999 999 999 999 999 999 999 99 +; -r3 - xor r10, xor rbx - removed on stoerit - they will be overwritten - no needf for theese. +; -r2 - add store it to store a larger than 8 byte - 64 bit value from register onto stack +; the imul and add are found from the net +; -r1 - remove strlen - string can be arbitrary, max value is 1024 +; v.08 factoriadic; change mov rdi 04 to rdi strlen +; v.07 - read from stdin +; v.06 use syscalls names from kernel instead of numerics +; v.05 include files - move functions to separate file +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + + +segment readable executable + +entry main + +include 'unistd64.inc' +include 'io.inc' ; the name of the file to be included + +main: + lea rdi, [prompt] ; load effective address of prompt + call print ; print to screen the prompt call 0x4000ce + + lea rsi, [buf] ; load effective address of buffer + mov rdi, 1024 ; 1024 number copy to rdi + call read ; read + call convert ; call 0x400136 + + mov rdi, rsi ; copy string we read to rdi + call print ; output to standard out + + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, sys_exit ; use sys.exit + syscall ; call OS + + +; accept string and convert each digit to base 10 +; takes as a parameter rsi which points to string +; mov rdi, rsi ; copy string we read to rdi + +convert: +; lea r8, [digitcnt] +; lea r8, [numberbuf] + xor rdx,rdx + xor rcx, rcx + xor rbx,rbx ; clear r8 + lea rdx,[numberbuf] + call loopString + ret + +loopString: ; 0x40013F + lodsb ; load byte string - a character is a byte - in ascii + ; and we entered ascii text into stdin + ; loadsb will load the source element - the number - identified by the + ; ESI/RSI register into the EAX/RAX register - for doubleword, AX for word, + ; AL for byte string (lodsb,lodsw,lodsd) + ; in this case we want just a single byte at a time to load into RAX + ; movzx rax, byte[rsi] + cmp al, 0xa ; compare to newlinecode +; je storeit ; in case this compare is equal jumpt to condition addcr + or al, al ; is the string that we read null terminated ? -has al reached the 0 marker + ; for null terminated strings? + jz addctr ; je 0x40014f jump to addctr address + and al, 0xf ; keep binary value of numerical digit +; imul rbx,10 ; jc storeit +; add rbx,rax ; store + mov [rdx],rax + inc rdx + inc rcx +; xor rbx,rbx + ; add [dbx], r8b +; inc rbx +; mov rax, rbx +; xor ax, ax ; zero out the lower bytes (rightmost byte) +; inc rdi +; inc rcx + jmp loopString ; return to beginning and do the same taks + + + +addctr: + push rax + push rbx + push rdx + mov rsi, buffered +.convertChar: + mov rax, rcx + xor rdx, rdx + div rbx + add rdx, '0' + cmp rdx, '9' + jbe .store + add rdx, 'A'-'0'-10 +.store: + dec rsi + mov [rsi], rdx + and rax, rax + jnz .convertChar + pop rdx + pop rbx + pop rax + ret + + +storeit: ; store result onto stack when carry bit is on + mov rbp,rsp ; wanna save that stack pointer so we don't get lost + sub rsp,64 ; and move down the stack 64 bytes (8*rbx) + stc ; this will clear the carry flagg and cmovc will not run - turn it on + cmovc r10,rbx ; cmovc will run if carry flag is set and copy the rbx to r10 - + ; should be another gp register ? + push r10 ; then push to stack that is now 8 bytes down + mov rsp,rbp ; point the stack pointer back from the base pointer to resume with + ; add rbx,rax + mov rbx,rax ; copy the rax register - this was holding a value that is neded rax + ; will not clear but will be cleared by next lodsb instruction + call loopString ; call the function - loopString - going back to lodsb + +segment readable writable ; this is where we put our data + prompt db 'Please input number to list its factoriadic values (1024 digits max): ' ,0 + buf rb 1024 + digitcnt db 16 dup(0) + numberbuf dq 1024 dup(?) + +buffered: + db 0 @@ -0,0 +1,112 @@ +format ELF64 executable 3 +; -r5 - move each value to the datasection not suppose to be in stack +; -r4 +; 0xD3C21BCECCEDA0FFFFFF +; 0x00000000000f423f 9 999 99 +8 bytes +; 0x8ac7230489e7fff6 9 999 999 999 999 999 990 STACK +; input: 9 999 999 999 999 999 999 999 99 +; -r3 - xor r10, xor rbx - removed on stoerit - they will be overwritten - no needf for theese. +; -r2 - add store it to store a larger than 8 byte - 64 bit value from register onto stack +; the imul and add are found from the net +; -r1 - remove strlen - string can be arbitrary, max value is 1024 +; v.08 factoriadic; change mov rdi 04 to rdi strlen +; v.07 - read from stdin +; v.06 use syscalls names from kernel instead of numerics +; v.05 include files - move functions to separate file +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + + +segment readable executable + +entry main + +include 'unistd64.inc' +include 'io.inc' ; the name of the file to be included + +main: + lea rdi, [prompt] ; load effective address of prompt + call print ; print to screen the prompt call 0x4000ce + + lea rsi, [buf] ; load effective address of buffer + mov rdi, 1024 ; 1024 number copy to rdi + call read ; read + call convert ; call 0x400136 + + mov rdi, rsi ; copy string we read to rdi + call print ; output to standard out + + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, sys_exit ; use sys.exit + syscall ; call OS + + +; accept string and convert each digit to base 10 +; takes as a parameter rsi which points to string +; mov rdi, rsi ; copy string we read to rdi + +convert: +; lea r8, [digitcnt] +; lea r8, [numberbuf] + xor rdx,rdx + xor rcx, rcx + xor rbx,rbx ; clear r8 + lea rdx,[numberbuf] + call loopString + ret + +loopString: ; 0x40013F + lodsb ; load byte string - a character is a byte - in ascii + ; and we entered ascii text into stdin + ; loadsb will load the source element - the number - identified by the + ; ESI/RSI register into the EAX/RAX register - for doubleword, AX for word, + ; AL for byte string (lodsb,lodsw,lodsd) + ; in this case we want just a single byte at a time to load into RAX + ; movzx rax, byte[rsi] + cmp al, 0xa ; compare to newlinecode +; je storeit ; in case this compare is equal jumpt to condition addcr + or al, al ; is the string that we read null terminated ? -has al reached the 0 marker + ; for null terminated strings? + jz addctr ; je 0x40014f jump to addctr address + and al, 0xf ; keep binary value of numerical digit +; imul rbx,10 ; jc storeit +; add rbx,rax ; store + mov [rdx],rax + inc rdx + inc rcx +; xor rbx,rbx + ; add [dbx], r8b +; inc rbx +; mov rax, rbx +; xor ax, ax ; zero out the lower bytes (rightmost byte) +; inc rdi +; inc rcx + jmp loopString ; return to beginning and do the same taks + + + +addctr: + mov [digitcnt], rcx ;add to counter how many digits -- ignored for now + ret + +storeit: ; store result onto stack when carry bit is on + mov rbp,rsp ; wanna save that stack pointer so we don't get lost + sub rsp,64 ; and move down the stack 64 bytes (8*rbx) + stc ; this will clear the carry flagg and cmovc will not run - turn it on + cmovc r10,rbx ; cmovc will run if carry flag is set and copy the rbx to r10 - + ; should be another gp register ? + push r10 ; then push to stack that is now 8 bytes down + mov rsp,rbp ; point the stack pointer back from the base pointer to resume with + ; add rbx,rax + mov rbx,rax ; copy the rax register - this was holding a value that is neded rax + ; will not clear but will be cleared by next lodsb instruction + call loopString ; call the function - loopString - going back to lodsb + +segment readable writable ; this is where we put our data + prompt db 'Please input number to list its factoriadic values (1024 digits max): ' ,0 + buf rb 1024 + digitcnt dq ? + numberbuf dq 1024 dup(?) + @@ -0,0 +1,139 @@ +format ELF64 executable 3 +; -r5 - move each value to the datasection not suppose to be in stack +; -r4 +; 0xD3C21BCECCEDA0FFFFFF +; 0x00000000000f423f 9 999 99 +8 bytes +; 0x8ac7230489e7fff6 9 999 999 999 999 999 990 STACK +; input: 9 999 999 999 999 999 999 999 99 +; -r3 - xor r10, xor rbx - removed on stoerit - they will be overwritten - no needf for theese. +; -r2 - add store it to store a larger than 8 byte - 64 bit value from register onto stack +; the imul and add are found from the net +; -r1 - remove strlen - string can be arbitrary, max value is 1024 +; v.08 factoriadic; change mov rdi 04 to rdi strlen +; v.07 - read from stdin +; v.06 use syscalls names from kernel instead of numerics +; v.05 include files - move functions to separate file +; v.04 bug in main after strlen it called print which called strlen again. core dump +; v.03 create a function to also print the string +; v.02 create function outside of main and +; calculate the length of the string + + +segment readable executable + +entry main + +include 'unistd64.inc' +include 'io.inc' ; the name of the file to be included + +main: + lea rdi, [prompt] ; load effective address of prompt + call print ; print to screen the prompt call 0x4000ce + + lea rsi, [buf] ; load effective address of buffer + mov rdi, 1024 ; 1024 number copy to rdi + call read ; read + call convert ; call 0x400136 + + mov rdi, rsi ; copy string we read to rdi + call print ; output to standard out + + xor rdi, rdi ; exit code of 0 exclusive or / zeroing out the register + mov rax, sys_exit ; use sys.exit + syscall ; call OS + + +; accept string and convert each digit to base 10 +; takes as a parameter rsi which points to string +; mov rdi, rsi ; copy string we read to rdi + +convert: +; lea r8, [digitcnt] +; lea r8, [numberbuf] + xor rdx,rdx + xor rcx, rcx + xor rbx,rbx ; clear r8 + lea rdx,[numberbuf] + call loopString + ret + +loopString: ; 0x40013F + lodsb ; load byte string - a character is a byte - in ascii + ; and we entered ascii text into stdin + ; loadsb will load the source element - the number - identified by the + ; ESI/RSI register into the EAX/RAX register - for doubleword, AX for word, + ; AL for byte string (lodsb,lodsw,lodsd) + ; in this case we want just a single byte at a time to load into RAX + ; movzx rax, byte[rsi] + cmp al, 0xa ; compare to newlinecode +; je storeit ; in case this compare is equal jumpt to condition addcr + or al, al ; is the string that we read null terminated ? -has al reached the 0 marker + ; for null terminated strings? + jz addctr ; je 0x40014f jump to addctr address + and al, 0xf ; keep binary value of numerical digit +; imul rbx,10 ; jc storeit +; add rbx,rax ; store + mov [rdx],rax + inc rdx + inc rcx +; xor rbx,rbx + ; add [dbx], r8b +; inc rbx +; mov rax, rbx +; xor ax, ax ; zero out the lower bytes (rightmost byte) +; inc rdi +; inc rcx + jmp loopString ; return to beginning and do the same taks + + +; from: https://stackoverflow.com/questions/7863094/how-can-i-convert-hex-to-decimal +; "123 % 10 gives us 3 and 123 / 10 = 12 conveniently gives us the correct number +; to work with in the next iteration" +; DIV stores both the quotient and remainder ax/dx +; after digit to string we need to store the result +addctr: + push rax ; save modified regusters + push rbx ; + push rdx ; + mov rax, rcx ; copy the rcx - the counted digits into rax + lea rsi, [buffered] ; start at end +.convertChar: + xor rdx, rdx ; clear the rdx regiter - remainder + mov rbx, 0xa ; put into rbx the number 10 - the base for our division + div rbx ; divides rax by rbx. rax is overriden, stores quotient, reminder is in rdx + add rdx, 0x30 ; ASCII Literal '0' add 0x30 + cmp rdx, 0x39 ; is it a hex digit + jbe .store ; if not then store it + add rdx, 'A'-'0'-10 ; +.store: + dec rsi + mov [rsi], dl + and rax, rax + jnz .convertChar + pop rdx + pop rbx + pop rax + ret + + +storeit: ; store result onto stack when carry bit is on + mov rbp,rsp ; wanna save that stack pointer so we don't get lost + sub rsp,64 ; and move down the stack 64 bytes (8*rbx) + stc ; this will clear the carry flagg and cmovc will not run - turn it on + cmovc r10,rbx ; cmovc will run if carry flag is set and copy the rbx to r10 - + ; should be another gp register ? + push r10 ; then push to stack that is now 8 bytes down + mov rsp,rbp ; point the stack pointer back from the base pointer to resume with + ; add rbx,rax + mov rbx,rax ; copy the rax register - this was holding a value that is neded rax + ; will not clear but will be cleared by next lodsb instruction + call loopString ; call the function - loopString - going back to lodsb + +segment readable writable ; this is where we put our data + prompt db 'Please input number to list its factoriadic values (1024 digits max): ' ,0 + buf rb 1024 + digitcnt db 16 dup(0) + numberbuf dq 1024 dup(?) + +buffered: + db 0