Użycie funkcji z C w ASM.

2015-10-29 08:49

Rejestracja: 4 lata temu

Ostatnio: 4 lata temu

0

Hej, probuje uzyc funkcji z C w assembly, czytalem poradniki, przykladowe kody ale coś mi ciągle nie idzie, to kod ktory mam do tej pory:

 .text
 .global main
main:
  movl $message, %edi
  call puts
  int $0x80
 .data
message:
  .string "hello world!\n"

Sam nie wiem np dlaczego na poczatku ładuje message do rejestru EDI, tak bylo w przykladowym programie ale hmmm, nie rozumiem dlaczego to robie, w innym kursie dodawalo sie też długość stringu w segmencie danych ale tutaj nie wiedzialem jak to wpasowac, probowalem czytac porady z roznych dokumentacji i to zlozyc jakos w calosc ale cos nie wyszlo, bede wdzieczny za pomoc.

edytowany 1x, ostatnio: Nejm, 2015-10-29 08:49

Pozostało 580 znaków

2015-10-29 09:39
Moderator

Rejestracja: 12 lat temu

Ostatnio: 29 minut temu

Lokalizacja: Wrocław

0

Ładujesz do tego rejestru, ponieważ funkcja oczekuje, że właśnie w nim będzie ciąg znaków. W jaki inny sposób mogłoby to działać?
Poza tym string powinien być null terminated.


Pozostało 580 znaków

2015-10-29 10:00

Rejestracja: 4 lata temu

Ostatnio: 4 lata temu

0

Nie wiem, nie ogarniam tych funkcji z C... na początek może lepiej spróbuje coś natywnie w assembly, teraz chce po prostu pobrać input od użytkownika a potem to wyświetlić, napisałem coś takiego ale też niezbyt działa, może powinienem gdzieś ten output zapisać czy coś ?

  .text
  .global _start
_start: 
        movl $3, %eax
        movl $0, %ebx
        int $0x80

        movl $4, %eax
        movl $1, %ebx
        int $0x80

        movl $1, %eax
        movl $0, %ebx
        int $0x80
edytowany 1x, ostatnio: Nejm, 2015-10-29 10:01

Pozostało 580 znaków

2015-10-29 11:40

Rejestracja: 6 lat temu

Ostatnio: 2 dni temu

0

ad 1 problemu, to nie działa ci to, bo nie stosujesz konwencji cdecl (zakładam że kompilujesz bez żadnych udziwnień), przed wywołaniem puts powinieneś umieścić parametr na stosie. Przez rejestry przekazujemy w fastcallu (i w sumie różnych innych, przykład - watcall, ale to szczegół).
Nie potrzebne też jest wywołanie int 80h bo z API systemowego nie korzystasz.
ad 2 problemu to rozwiązanie jest proste (coś takiego)

global _start
_start:
mov edx,4       ; długość textu
mov ecx,msg     ; ptr
mov ebx,1       ; deskryptor (stdout)
mov eax,4       ; nr syscalla
int 0x80        
section .data
msg: db "text"

Jeśli będziesz korzystał z puts to string powinien być null-terminated, jeśli z systemowego API, to nie jest to wymagane.

edytowany 2x, ostatnio: Proxima, 2015-10-29 11:43
watcall? Cóż to? - Patryk27 2015-10-29 11:51
Konwencja wywołania z Watcoma (16-bitowy kompilator C/C++ pod DOSa) starsi powinni pamiętać :- D. Ja korzystałem jak pisałem real-mode soft. - Proxima 2015-10-29 11:53
@Proxima: Watcom był przede wszystkim 32-bitowy, tzn. na tym się wsławił, 16-bitowy target miał ale to niejako przy okazji. Trwają prace nad forkiem x64. - Azarien 2015-10-29 12:02
@Azarien Tak? Być może był, przypuszczam że chodzi ci o te słynne mechanizmy Watcoma omijania limitu 1MB pamięci. Niemniej jednak 16 bit output code to jest jeden z tych przydatniejszych na dzień dzisiejszy, według mnie ficzerów. - Proxima 2015-10-29 12:07
DOS-owe gry które wyświetlały DOS4G/W Protected Mode Run-time były 32-bitowe i kompilowane właśnie Watcomem. - Azarien 2015-10-29 12:33

Pozostało 580 znaków

2015-10-29 11:53

Rejestracja: 4 lata temu

Ostatnio: 4 lata temu

0

a gdzie tu pobieram input ? Bo ja chce napisac program ktory pobierze tekst od uzytkownika i go wyswietli na output, a ten kod tylko wyswietla tekst "text"....

@EDIT
a co do samego kodu, to teraz wyglada on tak jak napisales:

  .text
  .global _start
_start: 
        movl $4, %edx
        movl $msg, %ecx
        movl $1, %ebx
        movl $4, %eax
        int $0x80

  .data
msg:
        db "text"

ale jak chce skompilowac to error:

as io.s -o io.o
io.s: Assembler messages:
io.s:12: Error: no such instruction: `db "text'

edytowany 5x, ostatnio: Nejm, 2015-10-29 12:03

Pozostało 580 znaków

2015-10-29 12:08

Rejestracja: 6 lat temu

Ostatnio: 2 dni temu

0
%define BUFFER_SIZE 32
section .text
global _start
_start:
        mov eax, 0x3
        mov ebx, 1
        mov ecx, buffer
        mov edx, BUFFER_SIZE
        int 80h

        mov eax, 0x4
        mov ebx, 1
        mov ecx, buffer
        mov edx, BUFFER_SIZE
        int 0x80

        mov eax, 0x01
        xor ebx, ebx
        int 80h

section .data
buffer: times BUFFER_SIZE db 0

Na swoją składnie przerób sobie sam.

Pozostało 580 znaków

2015-10-29 12:14

Rejestracja: 4 lata temu

Ostatnio: 4 lata temu

0

Dalej cos nie tak.

%define BUFFER_SIZE 32

  .text
  .global _start
_start: 
        movl $3, %eax
        movl $1, %ebx
        movl $buffer, %ecx
        movl $BUFFER_SIZE, %edx
        int $0x80

        movl $4, %eax
        movl $1, %ebx
        movl $buffer, %ecx
        movl $BUFFER_SIZE, %edx
        int $0x80

        movl $1, %eax
        xor %ebx, %ebx
        int $0x80

  .data
buffer: 
        times BUFFER_SIZE db 0

errory:

as io.s -o io.o
io.s: Assembler messages:
io.s:1: Error: junk at end of line, first unrecognized character is %' io.s:24: Error: no such instruction:times BUFFER_SIZE db 0'

oraz tutaj w tych linijkach:

        movl $3, %eax
        movl $1, %ebx
        movl $buffer, %ecx
        movl $BUFFER_SIZE, %edx
        int $0x80

Nie powinno byc:

mov $0, %ebx

?
Bo 0 to stdin a 1 to stdout, a wiec nie powinno byc tam 0 zamiast 1 ? oraz jak przetlumaczyc ten ostatni wiersz kodu

edytowany 2x, ostatnio: Nejm, 2015-10-29 12:28
times to dyrektywa NASM-a. nie wiem jaki jest odpowiednik pod GAS. - Azarien 2015-10-29 12:58
No ja właśnie też nie wiem i tu jest problem :< szukałem po dokumentacji ale nic znalezc nie moge... - Nejm 2015-10-29 13:03
jeśli możesz to polecam jednak NASM. as ma głupią składnię. - Azarien 2015-10-29 13:05
Wybrałem GAS ponieważ właśnie ta składnia mi się dużo bardziej podoba, zostanę przy tym. - Nejm 2015-10-29 13:09

Pozostało 580 znaków

2015-10-29 13:36

Rejestracja: 4 lata temu

Ostatnio: 4 lata temu

0

okej rozwiazalem problem, w gnu wyglada to tak:

  .equ BUFFER_SIZE, 32

  .text
  .global _start
_start: 
        movl $3, %eax
        movl $1, %ebx
        movl $buffer, %ecx
        movl $BUFFER_SIZE, %edx
        int $0x80

        movl $4, %eax
        movl $1, %ebx
        movl $buffer, %ecx
        movl $BUFFER_SIZE, %edx
        int $0x80

        movl $1, %eax
        xor %ebx, %ebx
        int $0x80

  .bss
        .lcomm buffer, BUFFER_SIZE

Pozostało 580 znaków

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0