Gå til innhold

Anbefalte innlegg

jeg tenker å lære meg litt assembly, har erfaring med høynivå-programmeringsspråk.

 

Jeg tenkte i første omgang å lage et program som summerer to heltall, for så å utvide det med å lese inn tall fra tastatur.

 

Har sett på google og youtube etter tutotirals som går gjennom hvordan man summerer to heltall, men finner ingenting.

 

Noen som kan hjelpe?

Endret av 13375k1133z
Lenke til kommentar
Videoannonse
Annonse

Jeg regner med det er x86 assembly du vil lære men er også viktig å presisere om du jobber med

16-bit, 32-bit eller 64 bit. Du kan feks prøve deg frem med en emulator eller noe

Eksempelvis er NASM en populær assembler for Linux. Det kan også være interessant å kompilere eksempelvis et veldig enkelt C++ program for så å se på koden med en disassembler.

Dog må du være obs på at dagens kompilatorer ofte involever optimiseringer som kan gjøre dette noe kryptisk å lese man kan allikevel være interessant. Stort sett er reverse engineering det mest nyttige man kan bruke assembly til idag.

 

Det viktigste å forstå med assemby når man starter er at man får en oversikt over registerne som brukes, hvordan de brukes, hvilke verdier som typisk blir lagret der osv. Nå har dagens prosessorer temmelig mange registre men i feks IA-32 ser man at de som oftest er i bruk er enkelte kontrollregistre, generrelle registre (EAX,EBX,ECX,EDX) og segmentregistre. Så disse er de første man bør se på. Du bør også være

fortrolig med hvordan en stakk (stabel) funger, da denne datatypen brukes til feks å referere til variabler eller å lagre returadresse for funksjonskall.

 

Hvis du har sett på assembly kode vil du også se at som regel brukes bare et mindre antall instrukser slik som aritmetiske operatorer, boolske operatorer, flyttoperasjoner og stakkoperasjoner - så disse er det stort sett greit å få oversikt over.

 

Edit:

http://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture

 

Denne linken ser feks ut til å ha en grei oversikt over registre og slikt.

Endret av fenderebest
Lenke til kommentar

Spørs litt på hvor verdiene ligger lagret - add instruksjonen i x86 kan feks brukes både på registre og minneadresser. Feks i IA-32 kunne vi hatt:

mov eax, 1

add eax, 2

 

Kan være at konstanter må gis i et annet format feks 0x01 istedet for 1 osv. Dette husker jeg ikke helt.

 

Merk at enkelte disassemblere bytter på rekkefølgen så man får add 2, eax eksempelvis.

Som jeg bemerket kan kompilert C++ kode leses som assembly vha en disassembler.

Endret av fenderebest
Lenke til kommentar

Hei, nedenfor ser du et veldig enkelt C-lignende (språket kalles AlboC - "A little bit of C") program oversatt til assembly. Dette er med en kompilator fra et kurs ved UiO som heter INF2100, og assembly-koden er ikke optimalisert i det hele tatt, hvert enkelt C-statement blir oversatt til en bestemt rekke av assembly-statements. Det er 32-bits (x86) kode som blir generert.

 

AlboC-program:

int main() {
  return 1+2;
}

Assembly-kode:

       .globl  main
main:  enter   $0,$0                # Start function main
       movl    $1,%eax              # 1
       pushl   %eax
       movl    $2,%eax              # 2
       movl    %eax,%ecx
       popl    %eax
       addl    %ecx,%eax            # Compute +
       jmp     .exit$main           # Return-statement
.exit$main:
       leave
       ret                          # End function main

En kompilator ville fort ha optimalisert bort hele adderingen, og i dette tilfellet endret koden til noe sånt som dette, men det er mindre viktig:

       .globl  main
main:  enter   $0,$0                # Start function main
       movl    $3,%eax              # 1+2
       leave
       ret                          # End function main
Lenke til kommentar

Siden du bruker NASM og Linux, kanskje følgende kodeeksemplet vil hjelpe.

 

C

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

Assembly

; 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

Se gjerne de andre eksemplene som viser forskjellig regning, med heltall/integer og float.

 

Java-programmer kan ikke gjøres direkte om til x86 assembly, da disse kjører under JVM, og har sitt eget instruksjonssett; det samme gjelder forresten også for Flash og .NET. Man kan fortsatt «disassemble» disse programmene, men instruksjonene er spesifikke for hver av disse plattformene.

Endret av ahw_
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...