1 Востаннє редагувалося navchalkin (20.03.2016 19:08:32)

Тема: Файли в ассемблері.

Всім привіт. Потрібно створити програму яка створює файл і записує в нього дані.
Я знайшов схожу в прикладах програми Emu8086, але вона не працює, тобто компілюється без помилок але файли не створює. Замість "PROGRAM HAS RETURNED CONTROL TO THE OPERATING SYSTEM" після компіляції видає "program terminated". Як виявилось, програма не створює папки і файли за вказаними адресами, бо чомусь бере за корненеву директорію c:\emu8086\MyBuild\.
Стандартну програму переробив, зменшив код і викинув все непотрібне. Працює тільки з директорією MyBuild. Можливо хтось знає в чім проблема?

org 100h

jmp start

file1 db "t1.txt", 0
handle dw ?   

text db "lazy dog jumps over red fox."
text_size = $ - offset text

start:
mov ax, cs
mov dx, ax
mov es, ax


            
; create and open file: c:\emu8086\MyBuild\t1.txt
mov ah, 3ch
mov cx, 0
mov dx, offset file1
int 21h
jc err2
mov handle, ax
; seek:
mov ah, 42h
mov bx, handle
mov al, 0
mov cx, 0
mov dx, 10
int 21h
; write to file:
mov ah, 40h
mov bx, handle
mov dx, offset text
mov cx, text_size
int 21h
; seek:
mov ah, 42h
mov bx, handle
mov al, 0
mov cx, 0
mov dx, 2
int 21h
; write to file:
mov ah, 40h
mov bx, handle
mov dx, offset text
mov cx, text_size
int 21h
; close c:\emu8086\MyBuild\t1.txt
mov ah, 3eh
mov bx, handle
int 21h
err2:
nop
            
ret 

2

Re: Файли в ассемблері.

Беріть знежучувач для DOS`а дивіться покроково що воно робить. Я б радив Turbo Debugger чи Insight.

Як виявилось, програма не створює папки і файли за вказаними адресами, бо чомусь бере за корненеву директорію c:\emu8086\MyBuild\.

Ну то змініть директорію, опис ДОС апі наче доступний всім бажаючим.

Подякували: navchalkin1

3 Востаннє редагувалося navchalkin (24.03.2016 09:07:22)

Re: Файли в ассемблері.

Всім привіт, пройшло трохи часу, всі попередні проблеми вирішив. Та тепер назріли нові.
Завдання: Розробити програму яка відслідковує появу вказаних цифр у числовому файлі. Створити файл В1 з чотирицифрових чисел шляхом введення з клавіатури, утворити файл В2 з чисел файлу В1, що мають один нуль, утворити файл В3 з чисел файлу В1, що мають дванулі і утворити файл В4 з чисел файлу В1, що мають три нулі.

Готовий код в мене є, тільки от із самим занесенням в файли В2, В3, В4 проблема. Заносить тільки перше чотирицифрове число в ці три файла, причом не звертає увагу на нулі. А повинно було би)
Коментований код:

org 100h      
jmp start                        
                        
b1 db 'kursach\b1.txt',0  
b2 db 'kursach\b2.txt',0
b3 db 'kursach\b3.txt',0
b4 db 'kursach\b4.txt',0   
k db 0                          ;лічильник нулів

handle dw ? 
handleb2 dw ?
handleb3 dw ?
handleb4 dw ?  

bufer  db 50 DUP (?)     
bufer2 db 50 DUP (?)   
size  = $ - offset bufer     
size2 = $ - offset bufer2   

start:              

mov ax, cs
mov dx, ax
mov es, ax

mov ah, 3ch
mov cx, 0
mov dx, offset b1          ;створення файлу В1
int 21h
mov handle, ax

;--------scan, check, write in file----------
       
level1:      
mov ah,1                                    
int 21h                         ;зчитування чисел з клавіатури
mov dl,al        
                                     
cmp al,13                     ;перевірка на Enter
je call write                  ;якщо так - тоді перехід на мітку запису в файл

mov [bufer+si], al         ;запис введених даних в масив
add si, 1        
jne level1 

level2:
    call b2proc                
    call b3proc                ;створення 3-х файлів В
    call b4proc
    call read                   ;процедура зчитування з файлу В1

;---------------------------------------------------proc-------------- 
                                        
;------------write to file b1-----------                                        
write proc
    mov ah, 42h
    mov bx, handle
    mov al, 0
    mov cx, 0
    mov dx, 0
    int 21h
    inc k    
  
    mov ah, 40h
    mov bx, handle
    mov dx, offset bufer    ;Процедура запису в В1
    mov cx, size
    int 21h     
    
    mov ah, 3eh
    mov bx, handle
    int 21h     
write endp      

;-----------create file b2, b3, b4------------
              
b2proc proc
    mov ah, 3ch
    mov cx, 0
    mov dx, offset b2
    int 21h
    mov handleb2, ax                  
b2proc endp    

b3proc proc
    mov ah, 3ch
    mov cx, 0
    mov dx, offset b3        ;створення 3-х файлів В
    int 21h
    mov handleb3, ax                  
b3proc endp

b4proc proc
    mov ah, 3ch
    mov cx, 0
    mov dx, offset b4
    int 21h
    mov handleb4, ax                  
b4proc endp
         
;----------read the file b1---------         
         
read proc 
    MOV AH,3DH             
    MOV AL,0                      
    MOV DX,OFFSET b1    
    INT 21H                   
    MOV HANDLE, AX               
        
    MOV AH,3FH              
    MOV BX,HANDLE         
    MOV CX,512              
    MOV DX,OFFSET bufer   ;читання з файлу В1            
    INT 21H
    CMP AX,512   
read endp  

;----------main logic----------

compare proc                 ;цикл перевірки зчитаних чисел з В1 і запису в інші файли
    mov cx, 50
    mov si, 0 
    mov di, 0
  input:
    mov al, [bufer+si]        ;заносим в регістр al si-й член масиву
   
    cmp al, 0                    ; перевіряєм на нуль
    je call increment          ; якщо 0 - інкрементуєм лічильник нуля
                        
    mov [bufer2+di],al   ;записуєм символ в буфер 2
    inc si                      ;інкрементуєм si
    inc di                      ;інкрементуєм di
    cmp di, 4                 ;якщо di = 4 -
    je call crossroads      ;- викликаєм процедуру "роздоріжжя"
   loop input      
    
compare endp       
            
;----------inc k-----------           
            
increment proc
    inc k                            ;процедура інкрементування нульвого лічильника
increment endp
     
;----------crossroads----------  

crossroads proc                 ;"роздоріжжя"
    
    cmp k, 1                      ;якщо к=1
    je call writeb2               ;викликаєм запис в файл В2
    
    cmp k, 2                       ;якщо к=2
    je call writeb3                ;викликаєм запис в файл В3 
    
    cmp k, 3                       ;якщо к=3
    je call writeb3                ;викликаєм запис в файл В2 

    mov k, 0                        
    mov di, 0                      ;обнуляєм лічильники
    inc si                            ;інкрементуєм регістр si щоб пропустити "пропуск" 
                                       ;(числа в файл заносяться через "пропуск", "пробіл")
crossroads endp   
                               
;---------write to files------------

;---------b2---------                              
writeb2 proc                      ;функції запису в файли числа з буфера2 
    mov ah, 42h
    mov bx, handleb2
    mov al, 0
    mov cx, 0
    mov dx, 0
    int 21h
    inc k    
  
    mov ah, 40h
    mov bx, handleb2
    mov dx, offset bufer2
    mov cx, size2
    int 21h     
    
    mov ah, 3eh
    mov bx, handleb2
    int 21h
writeb2 endp
           
;---------b3---------            
writeb3 proc
    mov ah, 42h
    mov bx, handleb3
    mov al, 0
    mov cx, 0
    mov dx, 0
    int 21h
    inc k    
  
    mov ah, 40h
    mov bx, handleb3
    mov dx, offset bufer2
    mov cx, size2
    int 21h     
    
    mov ah, 3eh
    mov bx, handleb3
    int 21h    
writeb3 endp

;---------b4--------- 
writeb4 proc
    mov ah, 42h
    mov bx, handleb4
    mov al, 0
    mov cx, 0
    mov dx, 0
    int 21h
    inc k    
  
    mov ah, 40h
    mov bx, handleb4
    mov dx, offset bufer2
    mov cx, size2
    int 21h     
    
    mov ah, 3eh
    mov bx, handleb4
    int 21h
writeb4 endp

ret

Проблема в тому, що воно записує тільки перше чотирицифрове число, і у всі файл, навіть якщо я запис в ті файли не викликаю. Може хтось підкаже як оптимізувати алгоритм? Буду дуже вдячним!

4

Re: Файли в ассемблері.

navchalkin, а в чому Ви працюєте?

5

Re: Файли в ассемблері.

Ярослав написав:

navchalkin, а в чому Ви працюєте?

Emu8086

6

Re: Файли в ассемблері.

цей цод не ваш і він не компілюється

7

Re: Файли в ассемблері.

0xDADA11C7 написав:

цей цод не ваш і він не компілюється

ні, цей код мій, і він компілюється. Може у нас різні версії емулятора.
ось скрини виконання програми:
Компіляція:
https://pp.сайт-злодій/c630425/v630425937/1c67d/NTv4eraPt2c.jpg
Успішне компілювання:
https://pp.сайт-злодій/c630425/v630425937/1c686/no95RvklpX8.jpg
Папка зі створеними файлами:
https://pp.сайт-злодій/c630425/v630425937/1c68f/heWXsxGoTYg.jpg
Перший файл із всіма числами:
https://pp.сайт-злодій/c630425/v630425937/1c698/4z-u4Ywf1gQ.jpg
Наступні 3 файли із першим чотирицифровим числом:
https://pp.сайт-злодій/c630425/v630425937/1c6a1/pONRLEpIjBE.jpg

Подякували: leofun011

8 Востаннє редагувалося navchalkin (25.03.2016 08:32:09)

Re: Файли в ассемблері.

Основна проблема в ось цьому куску програми.
Опишу детальніше.
Починається все з циклу для того щоб занести дані в буфер і порівняти їх із 0.
Заносим в al з буфера один символ (сітий член).
Наступним кроком перевіряєм на нуль, якщо істина - викликаєм процедуру increment, в якій інкрементуєм змінну k. Потрібно це для того щоб знати скільки нулів в чотирицифровому значенні. Коли  змінна інкрементувалась - наступним кроком цей символ заноситься в буфер2 із дітим членом (регістр di).
Інкрементується si та di.
Якщо di = 4 (масив заповнився 4-ма числами) - викликаєм процедуру crossroads, в якій повинен визначатись запис файлу відносно змінної k, в якій знаходиться кількість наших нулів, але відбувається чомусь не так, записуються всі файли з першим елементом (на нулі не перевіряється).
Можливо я якісь регістри пропустив, а їх треба обнулити?

;----------main logic----------
 
compare proc                 ;цикл перевірки зчитаних чисел з В1 і запису в інші файли
    mov cx, 50
    mov si, 0 
    mov di, 0
  input:
    mov al, [bufer+si]        ;заносим в регістр al si-й член масиву
   
    cmp al, 0                    ; перевіряєм на нуль
    je call increment          ; якщо 0 - інкрементуєм лічильник нуля
                        
    mov [bufer2+di],al   ;записуєм символ в буфер 2
    inc si                      ;інкрементуєм si
    inc di                      ;інкрементуєм di
    cmp di, 4                 ;якщо di = 4 -
    je call crossroads      ;- викликаєм процедуру "роздоріжжя"
   loop input      
    
compare endp       
            
;----------inc k-----------           
            
increment proc
    inc k                            ;процедура інкрементування нульвого лічильника
increment endp
     
;----------crossroads----------  
 
crossroads proc                 ;"роздоріжжя"
    
    cmp k, 1                      ;якщо к=1
    je call writeb2               ;викликаєм запис в файл В2
    
    cmp k, 2                       ;якщо к=2
    je call writeb3                ;викликаєм запис в файл В3 
    
    cmp k, 3                       ;якщо к=3
    je call writeb3                ;викликаєм запис в файл В2 
 
    mov k, 0                        
    mov di, 0                      ;обнуляєм лічильники
    inc si                            ;інкрементуєм регістр si щоб пропустити "пропуск" 
                                       ;(числа в файл заносяться через "пропуск", "пробіл")
crossroads endp   
                               
;---------write to files------------
 
;---------b2---------                              
writeb2 proc                      ;функції запису в файли числа з буфера2 
    mov ah, 42h
    mov bx, handleb2
    mov al, 0
    mov cx, 0
    mov dx, 0
    int 21h
    inc k    
  
    mov ah, 40h
    mov bx, handleb2
    mov dx, offset bufer2
    mov cx, size2
    int 21h     
    
    mov ah, 3eh
    mov bx, handleb2
    int 21h
writeb2 endp
           
;---------b3---------            
writeb3 proc
    mov ah, 42h
    mov bx, handleb3
    mov al, 0
    mov cx, 0
    mov dx, 0
    int 21h
    inc k    
  
    mov ah, 40h
    mov bx, handleb3
    mov dx, offset bufer2
    mov cx, size2
    int 21h     
    
    mov ah, 3eh
    mov bx, handleb3
    int 21h    
writeb3 endp
 
;---------b4--------- 
writeb4 proc
    mov ah, 42h
    mov bx, handleb4
    mov al, 0
    mov cx, 0
    mov dx, 0
    int 21h
    inc k    
  
    mov ah, 40h
    mov bx, handleb4
    mov dx, offset bufer2
    mov cx, size2
    int 21h     
    
    mov ah, 3eh
    mov bx, handleb4
    int 21h
writeb4 endp
 
ret

9

Re: Файли в ассемблері.

    je call crossroads      ;- викликаєм процедуру "роздоріжжя"

Цей рядок компілер не зїсть, томку код не ваш і він не компілюється. Ну і

    cmp al, 0                    ; перевіряєм на нуль

Визначтеся - ви число перевіряєте чи літеру?

Подякували: leofun011

10 Востаннє редагувалося navchalkin (25.03.2016 14:59:32)

Re: Файли в ассемблері.

0xDADA11C7 написав:
    je call crossroads      ;- викликаєм процедуру "роздоріжжя"

Цей рядок компілер не зїсть, томку код не ваш і він не компілюється.

ОМГ, а чий код? Це дурне ствердження мене заїло, бо писав його тільки я. Алгоритм придумав сам. В теорії все повинно працювати, а на практиці виходить по-іншому. В коді є фрагменти інших програм, але все тільки тому, що я економив час.
Я асемблер ще в неділю знав на рівні японської мови. Конішуа, і більше нічого. Я не знаю навіть більшості особливостей ассемблера, тому і звернувся по допомогу!
А за це - дякую, зрозумів в чому проблема.

0xDADA11C7 написав:

Ну і

    cmp al, 0                    ; перевіряєм на нуль

Визначтеся - ви число перевіряєте чи літеру?

11

Re: Файли в ассемблері.

Я асемблер ще в неділю знав на рівні японської мови. Конішуа, і більше нічого. Я не знаю навіть більшості особливостей ассемблера, тому і звернувся по допомогу!

Я залюбки допомагаю лише тим, хто сам намагається розібратися. Якби ви прийшли і сказали -- я таке написав і мійкод не компілюється, я б з радістю допоміг виправити помилку компіляції. А ви стверджуєте, що він компілюється, але не робить всього, що треба. Тому це вже инша справа.

12

Re: Файли в ассемблері.

0xDADA11C7 написав:

Я асемблер ще в неділю знав на рівні японської мови. Конішуа, і більше нічого. Я не знаю навіть більшості особливостей ассемблера, тому і звернувся по допомогу!

Я залюбки допомагаю лише тим, хто сам намагається розібратися. Якби ви прийшли і сказали -- я таке написав і мійкод не компілюється, я б з радістю допоміг виправити помилку компіляції. А ви стверджуєте, що він компілюється, але не робить всього, що треба. Тому це вже инша справа.

Дуже демократично.
Це як расизм, якщо твій код компілюється - то плювати що сам ти його писав, таким не помагаєм.
Ок, так би і зразу

13 Востаннє редагувалося navchalkin (18.04.2016 07:24:38)

Re: Файли в ассемблері.

Всім скептикам, що не вірили в мене:)
Код ще не "ахті", але ще чуть роботи і оптимізую максимально

.model small
.stack 256
.data      

msg0  db 13,10,'Enter number: $'  

b1    db 'b1.txt',0  
sizeB dw 0             

hndl2 dw 0
hndl3 dw 0
hndl4 dw 0
var      dw 0      

bufer db 80 DUP (?)     

.code
    assume ds:@data, es:@data, cs:@code

start:
    
    mov   ax,@data
    mov   ds,ax
    mov   es,ax

;\
; >-----\/----- enter the keyboard -----\/-----
;/                    
    mov   ah, 9             ;
    int   21h               ;
    mov   di, offset bufer  ;
    xor   bx, bx            ;
                            ;
level1:                     ;
    mov   cx, 4             ;
    mov   ah, 1             ;                           ;
@@:                         ; cykl vvodu 4 symboliv
    int   21h               ;
    cmp   al, 13            ;
    je    level2            ;
    stosb                   ;
    inc   bx                ;
loop @@                     ;
                            ;
    mov   ah, 2             ;
    mov   dl, ' '           ; pislya 4 symboliv stavum propusk 
    int   21h               ;
    stosb                   ;
    inc   bx                ;
    jmp   level1            ; i prodovzhuem vvid z klaviatury


;\
; >-----\/----- create file, compare number -----\/-----
;/

level2:  
    push  bx                ;
    mov   [sizeB], bx       ;
    mov   dx, offset b1     ;
                            ;
    call  createFile        ;   
    pop   cx                ;
    mov   bx,ax             ;
    mov   dx, offset bufer  ; 
                            ;
    call  writeFile         ; 
    call  closeFile         ;
    
;-----------------------------
    mov   cx, 3             ;
    mov   bp, hndl2  ;  
@1:                         ;
    inc   Byte Ptr [b1+1]   ;
    mov   dx, offset b1     ;
    call  createFile        ;
    
    cmp   cx, 3
    je    hd2
    cmp   cx, 2
    je    hd3
    cmp   cx, 1
    je    hd4    
    loop  @1                ;
                            ;
;-------------------------- ;
@5:
    mov   cx, [sizeB]  ;
    shr   cx, 2             ;
    mov   di, offset bufer  ;
                            ;
begin:                      ;
    push  cx                ;
    call  FindNull          ;     
    mov   var, bx    ;
    cmp   bx, 1             ;
    jnz   file3             ;
    mov   bx, hndl2  ;
    jmp   ok                ;
                            ;
file3:                      ;
    cmp   bx, 2             ;
    jnz   file4             ;
    mov   bx, hndl3  ;
    jmp   ok                ;
                            ;
file4:                      ;
    cmp   bx, 3             ;
    jnz   error             ;
    mov   bx, hndl4  ;
ok:                         ;
    mov   cx, 5             ;
    mov   dx, di            ;
    sub   dx, cx            ;
    call  writeFile         ;
error:                      ;
    pop   cx                ;
    loop  begin             ;
                            ;
;---------------------------;-----------
                            ;
    mov   cx, 3             ;
    mov   ax, offset hndl2  ;
@3:                         ;
    mov   bx, ax            ;
    call  CloseFile         ;
    add   ax, 2             ;
    loop  @3                ;
                            ;
    jmp   exit              ;
                            ;
;------------------PROCEDURE;---------------
                            ;
createFile:                 ;
    push  cx                ;
    mov   ah, 3ch           ;
    mov   cx, 20h           ;
    int   21h               ;
    pop   cx                ;
ret                         ;
                            ;
writeFile:                  ;
    push  cx                ;
    mov   ah, 40h           ;
    int   21h               ;
    pop   cx                ;
ret                         ;
                            ;
closeFile:                  ;
    mov   ah, 3eh           ;
    int   21h               ;
ret                         ;
                            ;
FindNull:                   ;
    mov   cx, 5             ;
    xor   bx, bx            ;
    mov   al, '0'           ;
@2:                         ;
    repne scasb             ;
    jcxz    endpro          ;
    inc   bx                ;
    jmp   @2                ;
endpro:
ret     

;-----------------------------
hd2:
    mov hndl2, ax
        dec   cx 
        jmp @1
ret
hd3:
    mov hndl3, ax            ;\    
        dec   cx             ; > Write HANDLE
        jmp @1                ;/
ret 
hd4:
    mov hndl4, ax
        dec   cx 
        jmp @5
ret
;--------------------------------
exit:                       ;
    xor   ax,ax             ;
    int   16h               ;
    int   20h               ;
                            ;
end start                   ;               
Подякували: koala, 0xDADA11C72