Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Elune 28. 05. 2014, 13:07:14
-
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.
-
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é.
-
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.
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.
-
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.
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.
-
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. :)