Langaði að skella inn lausn á þessu gert í Assembly.
#ishappy.s
.section .data
tala:
.int 0
thnmbr:
.ascii "The number "
erglod:
.ascii " is happy\n"
erekkiglod:
.ascii " is not happy\n"
.section .bss
.lcomm buffer 4
.lcomm geymsla 12
.section .text
.globl _start
_start:
nop
nop
nop
movl $0, %eax # lata vera fyrsta run
pushl %eax
movl $3, %eax # system call 3 , read
movl $0, %ebx # lesa fra stdin (keyboard)
movl $buffer, %ecx # skrifa i buffer
movl $4, %edx # lesa 4 byte
int $0x80 # kallid sjalft
xor %edx,%edx
xor %ebx,%ebx # nulla alla registera
xor %eax,%eax
xor %ecx,%ecx
movl $buffer, %edi # bua til pointer a buffer i edi
movl $geymsla, %edx # gera pointer a geymslu i edx
loop1:
movb (%edi), %al # lesa byte ur buffer og setja i al
cmp $10, %al # skoda hvort ad seinasti stafur var line feed (ascii 10)
je out # ef thad var 10 hoppa ur loop
subb $48, %al # breyta ascii gildi i tolu gildi
movb %al, (%edx) # skrifa toluna i geymsla
inc %edi # benda a naesta byte i buffer
inc %edx # benda a naesta byte i geymsla
inc %ebx # thetta er talning a hverso oft loopinn er tekinn
jmp loop1 # hoppa a loop1
out:
movb $0, (%edi) # skrifa 0 i seinasta staf sem var lesinn, er alltaf line feed
movl %ebx, tala # flytja talninguna i tala
movl $1, %eax # setja 1 i eax, verdur margfaldad med 10 i veldi tala
movl tala, %ecx # set tala i ecx. ecx er counter fyrir loop
xor %ebx, %ebx # nulla ebx
cmp $1, %ecx # skoda hvort ad loop1 var tekinn einusini
je over # ef tekid tha er thetta eins stafs tala
subl $1, %ecx # ecx er ad minnsta kosti 2 her og breytt i 1
xor %ebx, %ebx # nulla ebx
movw $10, %bx # setja 10 i bx, verdur margfaldad vid eax
xor %edx, %edx # nulla edx
loop2:
mulw %bx # margfalda that sem er i ax vid bx
loop loop2 # gera tad ecx sinnum, (veldi)
sal $16, %edx # shift left 16 sinnum, svarid ur bx*ax er sett i dx:ax
addl %edx, %eax # breyta svarinu ur dx:ax i eax
movl %eax, %ecx # setja svarid i ecx
movl $geymsla, %edx # gera pointer a geymslu
movb (%edx), %al # flytja fyrsta byte ur geymslu i al
mull %ecx # margfalda med rettum tug, ef ad slegid var inn 123, tha er her 100
movl $0, tala # setja 0 i tala
movl %eax, tala # flytja fyrsta tug i tala
movl $1, %ebx # setja 1 i ebx, counter
cmp $10, %ecx # ef skoda hvort slegin var inn 3 stafa tala
je over # ef ekki tha afgreida seinasta stafinn
movb $10, %bl # her verdur margfaldad med tug, buid ad afgreida 100
movl %ecx, %eax # setja 100 i eax
divb %bl # deila svo med 10
movl %eax, %ecx # setja svarid (10) i ecx
movl $geymsla, %edx # tharf aftur ad gera pointer tvi ad deiling skemmir edx
addl $1, %edx # leggja einn vid pointerinn, lesa naesta byte
movb (%edx), %al # lesa byte numer 2 og setja i al
mull %ecx # margfalda med 10
addl %eax, tala # leggja vid tad sem fyrir var, ef ad slegid var inn 123
movl $2, %ebx # tha er tala 120, setja 2 i ebx, counter
over:
movl $geymsla, %edx # gera nyjan pointer, til vonar og vara
xor %eax, %eax # nulla eax, lika til vara
addl %ebx, %edx # leggja counterinn vid pointer, segjir fjolda lesina byta
movb (%edx), %al # setja seinasta bytid i al
addl %eax, tala # leggja vid tala, tharf ekki ad margf thetta er eining
movl $1, %ecx # minnsta kosti einn
addl %ebx, %ecx # flytja counterinn i ecx
xor %edx, %edx # nulla edx
movl $geymsla, %ebx # gera pointer i ebx
loop3: #**********ALLT HER A UNDAN LES ASCII OG BREYTIR I ALLVORU TOLUR**
movb (%ebx), %al # flytja fyrstu toluna aftur i al
mulb %al # setja hana i annad veldi
movb %al, (%ebx) # skilar tolunni i 2 veldi til baka
inc %ebx # haekka pointer, taka naestu tolu
inc %edx # haekka counter
loop loop3
xor %eax, %eax # nulla eax
movl $geymsla, %ebx # gera pointer
loop4:
addb (%ebx), %al # leggja tolu i 2 veldi vid thad sem er i al, fyrst er thad 0
inc %ebx # haekka pointer, al dugar, thversumma ekki haerri en 3*81
cmp $1, %edx # skoda hvort thad er ein tala
je over2 # ef svo er hoppa
dec %edx # laekka counter
jmp loop4 # verdur haesta lagi tekin 2 1/2 sinnum
over2:
cmp $1,%al # skoda hvort ad thver summan se 1
je happy # tha fara i happy
cmp $10, %al # athuga hvort ad thversumma se laegri en 10
jb breyta1 # ef svo hoppa
cmp $100, %al # skoda hvort ad se laegra en 100
jb breyta2 # ef svo hoppa
popl %edx # fa her 2 til baka
jmp breyta3 # ef ad thversumman er haerri en 100 tha er thetta tekid
label1: # ******HER ER KOMID THEGAR BUID ER AD SKIPTA SUMMUNI I EINSTAKAR TOLUR********
popl %eax # her er fjoldi ferda sem teknar hafa verid sottar
addl $1, %eax # einum baett vid
pushl %eax # sett aftur i stackin
movl $geymsla, %ebx # her er pointer buin til
cmp $500,%eax # sed hvort ad teknar hafa verid 50 eda fleirri ferdir
jb loop3 # ef faerri tha er tekid atur
nhappy:
movl $4, %eax # her er system call 4 (write)
movl $1, %ebx # write to standard out (skjarinn)
movl $thnmbr, %ecx # pointer a hvad skal skrifa (thnmbr)
movl $11, %edx # hversu morg byte verda skrifud
int $0x80 # kallid sjalft
movl $4, %eax
movl $1, %ebx # tetta er tad sama nema annad sem verdur skrifad
movl $buffer, %ecx # thad sem upphaflega var lesid verdur skrifad ut (an line feed)
movl $3, %edx
int $0x80
movl $4, %eax # og tetta er aftur system call 4 (write)
movl $1, %ebx
movl $erekkiglod, %ecx # bara annar texti
movl $14, %edx
int $0x80
jmp loka # loka svo forritinu
happy:
movl $4, %eax # allt med felldu her
movl $1, %ebx
movl $thnmbr, %ecx
movl $11, %edx
int $0x80
movl $4, %eax # her er enn verid ad skrifa
movl $1, %ebx
movl $buffer, %ecx # bara verid ad lata etta litta nice ut
movl $3, %edx
int $0x80
movl $4, %eax # her er enn verid ad skrifa, system call 4
movl $1, %ebx
movl $erglod, %ecx # bara texti sem segir ad talan se glod
movl $10, %edx
int $0x80
loka:
movl $0, %ebx # setja 0 i ebx, etta er exir code
movl $1, %eax # system call 1 (exit)
int $0x80 # kallid sjalft, forritid buid
breyta1: # ***********skipta thversummu i 1 tolu*****************
movl $0, geymsla # nulla geymslu
movb %al, geymsla # setja thversummu i geymslu
movl $geymsla, %ebx # gera pointer
movl $1, %ecx # setja 1 i ecx,etta er counter
jmp label1 # hoppa i endan a algorithmanum
breyta2: # ***********skipta thversummu i 2 tolur****************
pushl %eax # setja thversummu i stackin
movl $geymsla, %edi # gera pointer
movl $0, %ebx # setja 0 i ebx
movl %ebx, (%edi) # nulla ut geymsla
movl $10, %ebx # setja 10 i ebx
divb %bl # deila med tug, fa ad vita fyrstu toluna
movb %al, (%edi) # svarid keumur i al, setja tad i geymslu
mulb %bl # margfalda fjolda af tugum med 10, ef 34, tha 30 her
popl %ecx # fa herna thversummuna til baka
subb %al, %cl # draga tugina fra toluni
movb %cl, 1(%edi) # eftir stendur eining sem er sett i holf 2 i geymslu
movl $geymsla, %ebx # gera pointer i geymslu
movl $2, %ecx # setja 2 i ecx, thetta er counter
jmp label1 # hoppa i endan
breyta3: # ***********skipta thversummu i 3 tolur****************
pushl %eax # setja tvesummu i stackin
movl $geymsla, %edi # gera pointer
movl $0, (%edi) # nulla ut geymslu
movl $100, %ebx # setja her 100 i ebx
divb %bl # deila thversummuni med 100
movb %al, (%edi) # setja svarid i geymsla
mulb %bl # margfalda svo toluna med 100
popl %ecx # fa her tversummuna
subb %al, %cl # draga svo fra hundrudin
movb %cl, %al # setja thau i al
pushl %ecx # setja afganginn i stackin
movl $10, %ebx # setja her 10 i ebx
divb %bl # deila afgangnum med 10
movb %al, 1(%edi) # setja svarid i geymsla+1
mulb %bl # margf med 10
popl %ecx # fa herna afganginn
subb %al, %cl # draga enn fra
movb %cl, 2(%edi) # eftir stendur eining setja hana i geymsla+2
movl $geymsla, %ebx # gera pointer
movl $3, %ecx #setja 3 i ecx segir hversu margar tolur eru
jmp label1 #klara algorithman
Þetta les eina tölu frá 0-999 frá lyklaborði og segir þér hvort að hún sé glöð eða ekki. Ég hefði getað látið þetta geta tekið við stærri tölum, en það hefði gert þetta töluvert lengra.
Þetta er ekki allveg “nettasta” lausnin sem sést hefur, en ég er ekki einhver proffessional assembly forritari.
Troðfyllti allt af commentum, svo að þeir sem hafa áhuga geta haft gagn af.