Ahoj,
naprogramoval jsem program v assembleru, který po zadání věty vypíše slova v opačném pořadí.
Např. "Ahoj jak se mas" >>> "mas se jak Ahoj"
Program pracuje na principu vyhledávání mezer. Při hledání mezery pracuji tedy s porovnáváním, jestli je znak menší než 32 v ASCI tabulce. Pracuje správně, dokud nejsou na vstupu znaky české abecedy (ěščřžýáíé).
Výstup v tomto případě vypadá např. takto "ě š čau ř" >>> "řauě š č"
Poradíte mi prosím, jak tento problém řešit? Nevím s rady.
Mam takove krute podezreni, ze americti imperialiste schvalne nepridali cestinu do ASCII. Sabotuji tve bohulibe usili, parchanti.
Citace od: Elune kdy 28. 05. 2014, 13:07:14
Poradíte mi prosím, jak tento problém řešit?
Dostudovat si jak funguje instrukce CMP.
Následně nepoužít JL/JNL, ale JB/JNB.
Začal bych tím že si vypíšeš v hexa ten vstup, tak uvidíš jak jsou kódóvány ty české znaky a třeba přijdeš na to proč se to chová tak jak se to chová.
Bez zdrojáku se těžko radí, ale tipuju, že tam máte znaménkové porovnání a ty české znaky mají zapnutý osmý bit, tedy vypadají jako záporné.
Citace od: Elune kdy 28. 05. 2014, 13:07:14
Pracuje správně, dokud nejsou na vstupu znaky české abecedy
Na vstupu zcela jistě nejsou znaky, ale bajty. Pro převádění mezi znaky a bajty slouží různé znakové sady (http://cs.wikipedia.org/wiki/Znakov%C3%A1_sada) a kódování. Znaková sada přiděluje jednotlivým znakům čísla, kódování pak určuje, jak se tato čísla zapisují do sekvence bajtů.
Vy tedy potřebujete vědět, v jaké znakové sadě máte vstup, následně rozpoznat jednotlivé znaky (třeba v kódování UTF-8 může být jeden znak vyjádřen jako jeden až šest bajtů), rozpoznat slova a prohodit jejich pořadí. Když to děláte podle bajtů, klidně za mezeru můžete považovat bajt, který je součástí nějakého znaku – a to bajtové vyjádření znaku roztrhnete na dvě části a uděláte z toho třeba dva úplně jiné znaky.
Citace od: Elune kdy 28. 05. 2014, 13:07:14
Při hledání mezery pracuji tedy s porovnáváním, jestli je znak menší než 32 v ASCI tabulce.
Ta tabulka se jmenuje ASCII a je to jedna ze znakových sad. Původní znaková sada ASCII je jen sedmibitová a české znaky s diakritiky neobsahuje.
Mezera má v ASCII (a v mnoha dalších znakových sadách) hodnotu 32 (dekadicky), měl byste tedy porovnávat na přesnou shodu. Znaky 0–31 jsou různé kontrolní znaky, rozhodně ne mezery. Třeba ve znakové sadě Unicode existují i další znaky, než jenom obyčejná mezera – neoddělitelná mezera, zúžená mezera apod. Jako oddělovač slov dokonce nemusí fungovat jen mezera, ale třeba také tabulátor nebo konec řádku.
Citace od: Filip Jirsák kdy 28. 05. 2014, 15:07:42
třeba v kódování UTF-8 může být jeden znak vyjádřen jako jeden až šest bajtů
Pokud vím, maximum jsou čtyři bajty.
Citace od: Filip Jirsák kdy 28. 05. 2014, 15:07:42
Když to děláte podle bajtů, klidně za mezeru můžete považovat bajt, který je součástí nějakého znaku – a to bajtové vyjádření znaku roztrhnete na dvě části a uděláte z toho třeba dva úplně jiné znaky.
Jen doplním, že v UTF-8 se tohle stát nemůže.
Pokud je to cvičení nebo snaha se naučit Assembler - smekám klobouk. Pokud je to součást reálného projektu - hmmm zrovna tady je assembler ne zcela optimální nástroj. Jinak předřečníci to vystihli zcela přesně.
Jde o cvičení. Můj dosavadní kód vypadá následovně.
.h8300s
.equ syscall, 0x1FF00
.equ GETC, 0x0111
.equ PUTC, 0x0112
.equ PUTS, 0x0114
.equ slm, 0x00FF
.data
string: .space slm
buffer_in: .space 1
buffer_out: .space 1
input: .asciz "Zadej vetu: "
result: .asciz "Obracene: "
newline: .asciz "\n"
.align 2
par1: .long buffer_in
par2: .long buffer_out
par3: .long input
par4: .long result
par_row: .long newline
.align 1
.space 0x100
stck:
.text
.global _start
_start: mov.l #stck,ER7
begin: mov.w #PUTS,R0
mov.l #par_row,ER1
jsr @syscall
mov.w #PUTS,R0
mov.l #par3,ER1
jsr @syscall
jsr @inp_str
mov.w #PUTS,R0
mov.l #par4,ER1
jsr @syscall
cykl1: cmp.l #0, ER3
bne cykl1_1
jmp cykl1_end
cykl1_1: mov.l #0,ER5
sub.l #1,ER3
mov.b @(string,ER3),R4L
cmp.b #32,R4L
ble cykl1_spa
cykl1_word:
add.l #1,ER5
cmp.l #0,ER3
beq cykl1_print
sub.l #1,ER3
mov.b @(string,ER3),R4L
cmp.b #32,R4l
bgt cykl1_word
add.l #1,ER3
jmp cykl1_print
cykl1_spa:
add.l #1,ER5
cmp.l #0,ER3
beq cykl1_print
sub.l #1,ER3
mov.b @(string,ER3),R4L
cmp.b #32,R4l
ble cykl1_spa
add.l #1,ER3
cykl1_print:
mov.l ER3,ER6
cykl1_print_1:
sub.l #1,ER5
mov.b @(string,ER6),R4L
mov.b R4L,@buffer_out
mov.w #PUTC,R0
mov.l #par2,ER1
jsr @syscall
add.l #1,ER6
cmp #0,ER5
bne cykl1_print_1
jmp cykl1
cykl1_end:
mov.w #PUTS,R0
mov.l #par_row,ER1
jsr @syscall
jmp begin
inp_str:
mov.l #0,ER3
cykl:
mov.w #GETC,R0
mov.l #par1,ER1
jsr @syscall
mov.b @buffer_in,R4L
cmp.b #13,R4L
beq cykl_end
cmp.l #slm,ER3
beq cykl
mov.b R4L,@(string,ER3)
add.l #1,ER3
jmp cykl
cykl_end:
mov.w #GETC,R0
mov.l #par1,ER1
jsr @syscall
rts
.end
Tak je to přesně to, co jsem psal. BGT a BLE jsou znaménková (signed) porovnání a čeština má typicky nastavený 8. bit, tj. u znaménkových porovnání se tváří jako záporná čísla, která jsou samozřejmě menší než 32. Nahraďte je bezznaménkovými BHI a BLO.
Citace od: Sten kdy 28. 05. 2014, 18:39:47
Tak je to přesně to, co jsem psal. BGT a BLE jsou znaménková (signed) porovnání a čeština má typicky nastavený 8. bit, tj. u znaménkových porovnání se tváří jako záporná čísla, která jsou samozřejmě menší než 32. Nahraďte je bezznaménkovými BHI a BLO.
Oprava: bezznaménková verze
BLE je
BLS,
BLO je bezznaménková verze
BLT.
Moc díky za pomoc. :)