Całość przy gcc dodaje -m32.
Nie mam pojęcia jak wyswietlic ta literkę.
Liczę na pomoc, Pozdrawiam :)
0
NASM avoids this undesirable situation by having a much simpler syntax for memory references. The rule is simply that any access to the contents of a memory location requires square brackets around the address, and any access to the address of a variable doesn't. So an instruction of the form mov ax,foo will always refer to a compile-time constant, whether it's an EQU or the address of a variable; and to access the contents of the variable bar, you must code mov ax,[bar].
This also means that NASM has no need for MASM's OFFSET keyword, since the MASM code mov ax,offset bar means exactly the same thing as NASM's mov ax,bar. If you're trying to get large amounts of MASM code to assemble sensibly under NASM, you can always code %idefine offset to make the preprocessor treat the OFFSET keyword as a no-op.
NASM nie posiada w swojej składni słowa kluczowego OFFSET. To nie MASM. Nie wspiera również takich instrukcji:
For this reason, NASM doesn't support the LODS, MOVS, STOS, SCAS, CMPS, INS, or OUTS instructions, but only supports the forms such as LODSB, MOVSW, and SCASD, which explicitly specify the size of the components of the strings being manipulated.
global _main
extern _printf
section .data
txt: db "Hello World", 0
format: db "%c", 0
section .text
_main:
xor eax, eax
mov eax, [txt]
push eax
push format
call _printf
add esp, 8
section .bss
Edit: //
global _main
extern _printf
section .data
txt: db "Hello World", 0
section .text
_main:
xor eax, eax
push ebp
mov ebp, esp
sub esp, 0x28
mov eax, txt
push eax
mov word[esp+0x4], 0x420
call _printf
pop eax
ret
section .bss
global _main
extern _printf
section .data
; 0xA
txt: db "Hello,World!", 10, 0
txt_len: equ $-txt
section .text
_main:
mov ecx, txt_len
l22:
push ecx
lea esi, [txt]
add esi, ecx
mov byte[esi+1], 0xA
mov byte[esi+2], 0x00
cmp ecx, 4
je label_here
pop ecx
dec ecx
cmp ecx, -1
jne l22
ret
label_here:
push esi
call _printf
add esp, 4
pop ecx
ret
section .bss
Wypisuje odpowiednią literę zależnie od liczby, którą jest przy tym cmp ecx, 4. Zamiast 4 można wpisać inną liczbę i wypisze inną literę.
global _main
extern _printf
section .data
; 0xA
txt: db "Hello,World!", 10, 0
txt_len: equ $-txt
section .text
_main:
mov ecx, txt_len
l22:
push ecx
lea esi, [txt]
add esi, ecx
mov byte[esi+1], 0xA
mov byte[esi+2], 0x00
push esi
call _printf
add esp, 4
pop ecx
dec ecx
cmp ecx, -1
jne l22
ret
section .bss
Wypisuje wszystko odwrotnie.
//
mov eax, [txt+1], wyrzuci "e". Pamiętaj, że istnieje takie coś jak konwencja wywołania parametrów w funkcji. Dla printf to jest "od prawej do lewej", czyli najpierw tekst do wypisania, a później format. Popatrz na składnię instrukcji printf. http://www.cplusplus.com/reference/cstdio/printf/ Char ma 8 bitów, więc musisz napisać db, czyli 1 bajt. int printf ( const char * format, ... );
W zasadzie to nadal nie wiem co to jest za składnia. Niby przypomina trochę MASM, trochę GNU Assembly, w każdym razie stworzyłem taki kod co drukuje literę H - nie wiem czy o to chodziło, ale podejrzewam, że chodziło Ci o wydrukowanie którejś z liter. Tak czy inaczej będziesz mógł sobie ten kod przebudować zgodnie z zadaniem, które masz do wykonania.
W zasadzie to nadal nie wiem co to jest za składnia. Niby przypomina trochę MASM, trochę GNU Assembly
NASM ma swoją składnię. Moim zdaniem lepszą od MASM/TASM (bo bardziej spójną) i od GNU as (bo ta to w ogóle jakieś dziwactwo).
Ale to wyżej to GNU z .intel_syntax, czyli taka jakaś hybryda.
0
Tak w sumie to potrzebuję wypisać wszystko po kolei ale nadal nie mogę tutaj licznika ogarnąć co by mi iterował po ciągu znaków
0
Po co Ci tutaj jakikolwiek licznik? Przecież funkcje ze standardowej biblioteki C typu puts lub printf (chociaż nawiasem mówiąc kompilator przy wypisywaniu ciągu znaków bez podanego formatu i tak zamieni printf na puts) wypiszą ten ciąg znaków za Ciebie - wystarczy, że przekażesz do nich jego adres.
Nie wiem czy wiesz, ale ta dyrektywa .asciz jest po to, żeby z literału utworzyć C-String, czyli dany literał dzięki tej dyrektywie jest z automatu uzupełniany na końcu NULL-bytem -> http://bravegnu.org/gnu-eprog/asm-directives.html
0
Pierwszą literkę można wyświetlić korzystając z ciągu formatującego, jeśli musi być printf. Alternatywnie za pomocą write.
Przerobiony przykład podany przez ciebie:
.intel_syntax noprefix
.global main
.text
main:
push ebp /*tworzysz ramkę stosu*/
mov ebp,esp
push offset mesg /*odłożenie argumentu na stosie*/
push offset format /*format na stos*/
call printf
add esp, 8 /*zdjęcie argumentów ze stosu*/
mov esp,ebp /*przywracasz poprzednią ramkę stosu*/
pop ebp
xor eax,eax /*zwrócenie bez błedu (zerowanie eax)*/
ret /*wracasz z funkcji*/
.data
mesg:
.asciz "Hello, world\n"
format:
.asciz "%.1s\n"
0
Okej, troszkę skłamałem. Ostateczny cel to zamiana literek duże na małe a małe na duże, wypisując je kolejno jedna po drugiej, nie jako ciąg w jednej linii. Tak, wiem można by wpisać napis tak:
Ale to się mija z moim celem. Stąd mowa o liczniku i iterowaniu :P.
0
Tu masz kod zamieniający małe litery na duże i duże na małe. Napisałem go w NASM, bo tego Twojego Assemblera nie znam. Możesz sobie zamienić kod z NASM na swój Assembler. Skoro w jednym z komentarzy pisałeś, że masz to zrobić w ramach zajęć to powinieneś po prostu wiedzieć jakiego tam Assemblera używacie. Gdybyś mi napisał, o którego chodzi byłoby mi łatwiej się dostosować i może czegoś nowego nauczyć, a tak to musisz się męczyć samemu.
Natomiast zamiana liter z małych na duże i na odwrót możesz zrobić za pomocą czegoś takiego:
cld
mov esi, offset mesg
mov edi,esi
loop:
lodsb
cmp al,0
jz print
small:
/*Twój kod sprawdzający i zmieniający z małej na dużą (może mieć 6 linii)
big:
/* Twój kod sprawdzający i zamieniający z dużej na małą (może mieć 5 linii)*/
next:
stosb
jmp loop
1 użytkowników online, w tym zalogowanych: 0, gości: 1