» »

asm - vnos stevilk s tipkovnice

asm - vnos stevilk s tipkovnice

scarymovie ::

Pozdravljeni, zanima me kako v assemblerju napisat program, ki sprejme tri stevila vnesena preko tipkovnice.

section .data
  izpis db "Vnesi 3 stevila: ", 10, 0
  niz1 db "%d%d%d", 0
  izpis_st db "%d", 10, 0
  stevilo1 db 1
  stevilo2 db 1
  stevilo3 db 1
section .text
main:
push dword izpis
  call _printf
  push stevilo3
  push stevilo2
  push stevilo1
  push dword niz1
  call _scanf
  add esp, 28

To sem napisal, vendar če dam izpis za stevilo2 ali stevilo3 mi ne izpiše prav.

c0dehunter ::

Pozdravljen sošolc (najvrjetneje) :)

Kolikor vem, bereš števila vsakega posebej. Tako da mora biti format niz1 "%d" in ne "%d%d%d". Potem pa za vsako število najprej push steviloX, nato push format, nato klic _scanf. Potem pa ponoviš za vsa tri števila.

Še nekaj... Če delaš nalogo za RA, kjer je treba najti največje število, potem ne delaš prav. V assemblerju napišeš samo funkcijo, ki pa jo potem kličeš iz C glavnega programa.

Lp
I do not agree with what you have to say,
but I'll defend to the death your right to say it.

scarymovie ::

Ooo, pozdrvljen sošolc :)

glede branja sem poskusil tudi tako:
section .data
  izpis db "Vnesi 3 stevila: ", 10, 0
  niz1 db "%d", 0
  niz2 db "%d", 0
  niz3 db "%d", 0
  izpis_st db "%d", 10, 0

_main:
  pushad
  push dword izpis
  call _printf
  push stevilo1
  push dword niz1
  call _scanf
  add esp, 12
  push stevilo2
  push dword niz2
  call _scanf
  add esp, 8
  push stevilo3
  push dword niz3
  call _scanf
  add esp, 8


pa mi ne izpiše prav števil, oz. mi izpiše samo stevilo3 vredu, ostale pa ne.
Naprej pa pol moramo delat v C-ju?? Ker v navodilih o tem ne piše nič. To je mogoče omenil kaj na vajah? Jaz sem nalogo zdaj rešo tako da sem shrano neke random vrednosti v eax, ebx in ecx, potem pa v funkciji poiskal največje, pa tak mi je ratal. Kak je pa pol v C-ju? Tam napišem celetone program, funkcija pa je potem iz assemblerja?

pa hvala ker si me opomnil, ker drugače bi jaz oddal celotno nalogo v asm :)
LP

c0dehunter ::

Branje lahko takle narediš:

format_vpis db "%d",0		;definiramo format vpisa
stevilo1 dd 0						;definiramo stevila
stevilo2 dd 0						
stevilo3 dd 0						

.
.
.

push dword stevilo1       ;na sklad potisnemo lokacijo v pomnilniku
push dword format_vpis    ;na sklad potisnemo format
call _scanf             ;prebremo stevilo
add esp,8                     ;izpraznimo sklad
mov ecx,[stevilo1] ;v ecx register shranimo prebrano stevilo

push dword stevilo2       ;na sklad potisnemo lokacijo v pomnilniku
push dword format_vpis    ;na sklad potisnemo format
call _scanf             ;prebremo stevilo
add esp,8                     ;izpraznimo sklad
mov edx,[stevilo2] ;v edx register shranimo prebrano stevilo
.
.
.


Glede izvedbe pa nevem, na strani za vaje je pat tak čudno napisano :) Ker funkcijo lahk kličeš iz c programa, ali pa vse narediš v samem zbirniku.
Js sm naredu c varjanto, ampak tut nism sigurn, da moreš na ta način. Dela pa.

V zbirnem jeziku napišite funkcijo max3, ki prejme 3 cela števila in vrne največje. V glavnem programu prikažite primer uporabe funkcije.

Mogoče kdo drug ve kako bi blo treba naredit?
I do not agree with what you have to say,
but I'll defend to the death your right to say it.

Zgodovina sprememb…

scarymovie ::

zdravo

vprašal bi kako naj naslednjo c++ kodo pretvorim v asm kodo?
#include <iostream.h>

int rek(int n)
{
    if ((n==0) || (n==1))
       return 1;
    else if (n==2)
         return 7;
    else
        return rek(n-3)+rek(n-2);
}

int main ()
{
    for (int i=3; i<=15; i++)
    {
        cout << rek(i) << endl;
    }
    
    system("pause");
    return 0;
}



v asm sem napisal naslednjo kodo:
bits 32
extern _printf, _scanf
global _main

section .data
	izpis db "%d",10,0 ;za izpis zaporedja
section .text

_rekurzija:
      mov eax, [esp+4] ;v eax shranimo n
      cmp eax, 1       ;ali je n=1?
      je .ena          ;pojdi na funkcijo ena(izpolnimo pogoj)
      cmp eax, 2       ;ali je n=2?
      je .dva          ;pojdi na funkcijo dva(izpolnimo pogoj)
      cmp eax, 0       ;ali je n=0?
      je .nula         ;pojdi na funkcijo nula(izpolnimo pogoj)

      sub eax, 3       ;(n-3)
      mov edx, eax     ;v register edx shranimo vrednost n-3
      push eax         ;v sklad shranimo parameter za naslednjo funkcijo
      call _rekurzija  ;klic funkcije
      pop ebx          ;prvi rezultat
      mov eax, edx     ;v eax register prenesemo vrednost edx
      inc eax          ;(n-2)
      push eax         ;v sklad shranimo parameter za naslednjo funkcijo
      call _rekurzija   ;klic funkcije
      pop eax          ;drugi rezultat
      add eax, ebx     ;sestejemo oba rezultata
      jmp .konec         ;pojdi na konec
.ena:
      mov eax, 1      ;v eax shranimo 1 (pogoj)
      jmp .konec      ;pojdi na konec
.dva:
      mov eax, 7      ;v eax shranimo 7 (pogoj)
      jmp .konec      ;pojdi na konec
.nula:
      mov eax, 1      ;v eax shranimo 1 (pogoj)
      jmp .konec      ;pojdi na konec
.konec:
      ret             ;izhod

_main:
      pushad
      mov ecx, 3      ;v register shranimo stevilo 3
.zanka:
      push ecx        ;v sklad shranimo ecx za zanko
      push ecx        ;v sklad shranimo ecx za funkcijo
      call _rekurzija ;klic rekurzivne funkcije
      add esp, 4      ;izbrisemo vrh sklada

      push eax         ;v sklad shranimo vrnjeno stevilo od funkcije
      push dword izpis ;v sklad shranimo izpis
      call _printf     ;izpis stevila
      add esp, 8       ;pocistimo sklad do predzadnjega dela

      pop ecx          ;iz sklada vzamemo ecx(stevec)
      inc ecx          ;povecamo stevec za 1
      cmp ecx, 15      ;primerjamo ce je stevec manjsi enak 15
      jle .zanka       ;če je ponovimo

      popad
      ret


vendar rekurzija ne deluje pravilno in nevem kaj bi lahko bilo narobe?

hvala,
LP

scarymovie ::

no tezavo smo našli, vendar jo nevemo rešit...

je pa takole:

ko rekurzivno klicem n-3 nevem shranit prvotni n-3 ker mi funkcija ob vsakem rekurzivnem klicu spremeni vrednost registra.
Torej potrebujem prvotno n-3 vrednost da jo lahko potem uporabim za n-2

Torej bol pregledno:
      sub eax, 3       ;(n-3)
      mov edx, eax     ;v register edx shranimo vrednost n-3                      <---tu se prepiše ob rekurzivnem klicu
      push eax         ;v sklad shranimo parameter za naslednjo funkcijo
      call _rekurzija  ;klic funkcije
      pop ebx          ;prvi rezultat
      mov eax, edx     ;v eax register prenesemo vrednost edx			 <--tu pa rabim prvotno vrednost n
      inc eax          ;(n-2)							<---da lahko tu odstejem
      push eax         ;v sklad shranimo parameter za naslednjo funkcijo
      call _rekurzija   ;klic funkcije
      pop eax          ;drugi rezultat
      add eax, ebx     ;sestejemo oba rezultata
      jmp .konec         ;pojdi na konec



Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

C programiranje (strani: 1 2 3 )

Oddelek: Programiranje
14126733 (17029) amacar
»

[ASM] Pomoč, ne najdem napake

Oddelek: Programiranje
51026 (902) c0dehunter
»

[Assembler] scanf How-To

Oddelek: Programiranje
61497 (1424) c0dehunter
»

[nasm] scanf

Oddelek: Programiranje
272795 (2522) Brane2
»

[NALOGA][NASM] problem pri povezovanju s C-jevskimi funkcijami

Oddelek: Programiranje
61311 (1169) c00L3r

Več podobnih tem