Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
0 / 0 / 0
Регистрация: 02.03.2017
Сообщений: 23

Файл: Как считать числа из файла в переменную типа DW (В идеале - массив DW)?

17.11.2017, 11:59. Показов 2610. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Возникла проблема, как считать числа из файла в переменную типа DW. В идеале - массив DW. Может есть у кого какие-нибудь наброски или просто можете как-нибудь объяснить. Буду очень благодарен.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
17.11.2017, 11:59
Ответы с готовыми решениями:

Как считать файл с текстом в одну переменную типа string максимально быстро?
Как считать файл с текстом в одну переменную типа string максимально быстро? Текст художественный. Лежит в простых .txt Простой...

Считать числа типа double из файла и записать их в массив
Проблема следущая: нужна программа которая считывает числа типа double из файла (в моем случае это индексы валютного курса) и записывает их...

Считать файл в переменную типа System::String
Ну, рассказывайте :) что-то с std::wifstream и методом get() не выходит. std::wifstream getfile; String ^test=""; ...

22
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6206 / 2441 / 402
Регистрация: 29.07.2014
Сообщений: 3,174
Записей в блоге: 4
17.11.2017, 18:23
Цитата Сообщение от Ryoma Посмотреть сообщение
или просто можете как-нибудь объяснить.
открываешь файл, считываешь с него числа в свой буфер, закрываешь файл. Числа в буфере!
В чём именно проблема?
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8644 / 4479 / 1669
Регистрация: 01.02.2015
Сообщений: 13,883
Записей в блоге: 11
17.11.2017, 22:24
Чтение из файла, перевод строки в число
0
0 / 0 / 0
Регистрация: 02.03.2017
Сообщений: 23
18.11.2017, 15:16  [ТС]
Окей, я считаю в db. А как потом это все в DW перевести?
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8644 / 4479 / 1669
Регистрация: 01.02.2015
Сообщений: 13,883
Записей в блоге: 11
18.11.2017, 16:10
Ой, невнимательно прочитал.
Тогда там всё тоже самое, но Str2Num возьмите отсюда
Ввод и вывод чисел в различных системах счисления

Добавлено через 22 минуты
Там идея в том, что из файла считываются символы и добавляются в строку пока не встретится пробел (разделитель). После этого строка передаётся для преобразования в число. Т.е. сначала выделяется слово, ограниченное пробелами, а потом это слово преобразуется в число.

А лучше приведите исходный текст задания.
0
0 / 0 / 0
Регистрация: 02.03.2017
Сообщений: 23
19.11.2017, 16:28  [ТС]
Спасибо, и, еще. Попытался разобраться, но не разобрался с внесением в регистры. Вот, у меня есть следующее:

Assembler
1
2
tempvar dw ?
    num1 db '132'
И вот такое:
Assembler
1
2
3
lea     si, num2+1
    lea     di, tempvar
    call    Str2Num
В итоге, в DI неправильный результат. Может подскажете, что я не так делаю что-то?

Добавлено через 7 минут
Там вместо lea si, num2+1 у меня lea si, num1+1. Так что с этим все правильно. Просто описка.
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8644 / 4479 / 1669
Регистрация: 01.02.2015
Сообщений: 13,883
Записей в блоге: 11
19.11.2017, 16:39
Так в описании Str2Num
Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
На вход в процедуру Str2Num передаётся указатель на строку Pascal типа - т.е. по смещению 0 в строке находится её длина.
Т.е.
Assembler
1
    num1 db 3, '132'
0
0 / 0 / 0
Регистрация: 02.03.2017
Сообщений: 23
19.11.2017, 16:52  [ТС]
Оооокей, а если я формирую строку динамически, как мне добавить её размер?

Добавлено через 7 минут
+, опять же, добавил количество символов. Ничего не поменялось. В DI выводит постоянно 221.
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8644 / 4479 / 1669
Регистрация: 01.02.2015
Сообщений: 13,883
Записей в блоге: 11
19.11.2017, 17:23
Нет хрустального шара. Ничего не вижу.
0
0 / 0 / 0
Регистрация: 02.03.2017
Сообщений: 23
19.11.2017, 17:27  [ТС]
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
DATA SEGMENT
    path db "abc.txt",0 ; имя файла для октрытия
    buf  db ?
    path2 db 'qwe.txt', 0
    f_Handle1 dw ?
    f_Handle2 dw ?
    buff db 200 dup('$')
    tempvar dw ?
    array db ?
    num1 db 3, '132'
 
    num2 db ?
DATA ENDS
 
SSEG SEGMENT STACK
      db 200 dup(?)
SSEG ENDS
 
CODE SEGMENT
 ASSUME CS:CODE, DS:DATA, SS:SSEG
  begin:
    mov ax,DATA ; настроим DS
    mov DS,ax       ; на реальный сегмент
    
    
filework:
    lea     si, num1+1
    lea     di, tempvar
    call    Str2Num
    
    mov ax, di
    call OutInt
    
   exit:            ; завершаем программу
    mov ah,4ch
    int 21h
    
OutInt proc 
    xor     cx, cx
    mov     bx, 10 ; основание сс. 10 для десятеричной и т.п.
oi2:
    xor     dx,dx
    div     bx
    
    push    dx
    inc     cx
    
    test    ax, ax
    jnz     oi2
    
    mov     ah, 02h
oi3:
    pop     dx
 
    add     dl, '0'
    int     21h
    
    loop    oi3
    
    ret
 
OutInt endp
Str2Num proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    ds
        push    es
 
        push    ds
        pop     es
 
        mov     cl, ds:[si]
        xor     ch, ch
 
        inc     si
 
        mov     bx, 10
        xor     ax, ax
 
@@Loop:
        mul     bx         ; умножаем ax на 10 ( dx:ax=ax*bx )
        mov     [di], ax   ; игнорируем старшее слово
        cmp     dx, 0      ; проверяем, результат на переполнение
        jnz     @@Error
 
        mov     al, [si]   ; Преобразуем следующий символ в число
        cmp     al, '0'
        jb      @@Error
        cmp     al, '9'
        ja      @@Error
        sub     al, '0'
        xor     ah, ah
        add     ax, [di]
        jc      @@Error    ; Если сумма больше 65535
        inc     si
 
        loop    @@Loop
 
        mov     [di], ax
        clc
        pop     es
        pop     ds
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
@@Error:
        xor     ax, ax
        mov     [di], ax
        stc
        pop     es
        pop     ds
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
Str2Num endp
CODE ENDS
  end begin
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8644 / 4479 / 1669
Регистрация: 01.02.2015
Сообщений: 13,883
Записей в блоге: 11
19.11.2017, 18:33
Запустите мой код из примера.

Разница - из файла я набираю по одному символу новую строку пока не встречу разделитель (пробел), поэтому её длина известна. Эту строку передаю на преобразование в число.

Это считается "формирую строку динамически"?
0
0 / 0 / 0
Регистрация: 02.03.2017
Сообщений: 23
19.11.2017, 22:30  [ТС]
Окей, я сделал все точно так же. Но он по итогу выводит нули.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
DATA SEGMENT
    path db "abc.txt",0 ; имя файла для октрытия
    buf  db ?
    path2 db 'qwe.txt', 0
    f_Handle1 dw ?
    f_Handle2 dw ?
    buff db 200 dup('$')
    counter dw 0
    arraySize dw 20
    array db 6, 0, 6 dup(0)  
    indexI dw 0
    indexJ dw 0
    
    tempvar dw 0
    
    localcount db 0
DATA ENDS
 
SSEG SEGMENT STACK
      db 200 dup(?)
SSEG ENDS
 
CODE SEGMENT
 ASSUME CS:CODE, DS:DATA, SS:SSEG
  begin:
    mov ax,DATA ; настроим DS
    mov DS,ax       ; на реальный сегмент
    ;открываем файл
    mov ax,3d00h    ; открываем для чтения
    lea dx,path     ; DS:dx указатель на имя файла
    int 21h     ; в ax деcкриптор файла
    jc exit     ; если поднят флаг С, то ошибка открытия
    
    mov bx,ax       ; копируем в bx указатель файла
    xor cx,cx
    xor dx,dx
    mov ax,4200h
    int 21h     ; идем к началу файла
 
    mov si, 1
   out_str:
    mov ah,3fh      ; будем читать из файла
    mov cx,1        ; 1 байт
    lea dx,buf      ; в память buf
    int 21h        
    
    mov dl, buf
    cmp dl, '!'
    je close
 
    cmp dl, ' '
    je nextPtr
    
    mov array[si], dl
    inc si
    inc counter
    inc localcount
    
 
    nextPtr:
    cmp dl,' '
    jne out_str
    
    
    
    
    push cx
    push ax
    mov si, 0
    ;pop dl
    mov localcount,0
    
    lea si, array+1
    lea di, tempvar
    call Str2Num
    
    mov ax, tempvar
    mov cx, 10
    call Show_ax
    
    pop ax
    pop cx
    
    
    mov counter, 0
    mov si, 0
    jmp out_str
   close:           ; закрываем файл, после чтения
    mov ah,3eh
    int 21h
    
    output:
;   mov si, 0
;   mov cx, counter
;   loop1:
;       mov dl, array[si]
;       mov ah, 2
;       int 21h
;       inc si
;   loop loop1
    
   exit:            ; завершаем программу
    mov ah,4ch
    int 21h
 
Show_ax PROC
;        mov     cx, 10
        xor     di, di          ; di - кол. цифр в числе
@@Conv:
        xor     dx, dx
        div     cx              ; dl = num mod 10
        add     dl, '0'         ; перевод в символьный формат
        inc     di
        push    dx              ; складываем в стэк
        or      ax, ax
        jnz     @@conv
        ; выводим из стэка на экран
@@Show:
        pop     dx              ; dl = очередной символ
        mov     ah, 2           ; ah - функция вывода символа на экран
        int     21h
        dec     di              ; повторяем пока di<>0
        jnz     @@show
        ret
Show_ax ENDP
; CY - флаг переноса (при ошибке - установлен, иначе - сброшен)
Str2Num PROC
        push    ax
        push    bx
        push    cx
        push    dx
        push    ds
        push    es
 
        push    ds
        pop     es
 
        mov     cl, ds:[si]
        xor     ch, ch
 
        inc     si
 
        mov     bx, 10
        xor     ax, ax
 
@@Loop:
        mul     bx         ; умножаем ax на 10 ( dx:ax=ax*bx )
        mov     [di], ax   ; игнорируем старшее слово
        cmp     dx, 0      ; проверяем, результат на переполнение
        jnz     @@Error
 
        mov     al, [si]   ; Преобразуем следующий символ в число
        cmp     al, '0'
        jb      @@Error
        cmp     al, '9'
        ja      @@Error
        sub     al, '0'
        xor     ah, ah
        add     ax, [di]
        jc      @@Error    ; Если сумма больше 65535
        inc     si
 
        loop    @@Loop
 
        mov     [di], ax
        clc
        pop     es
        pop     ds
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
@@Error:
        xor     ax, ax
        mov     [di], ax
        stc
        pop     es
        pop     ds
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
Str2Num ENDP
 
out_value proc near ;выводит на экран число в ax
        cmp bl, 10 ;сравниваем с 10
            jz out_value_l1 ;если равно 10
                jc out_value_l1 ;если меньше 10
                    mov bl, 10 ;записываем в bl 10
        out_value_l1: ;теперь bl меньше либо равно 10
        cmp bl, 0 ;сравниваем с 0
            jnz out_value_l2 ;не равно 0
                mov bl, 10 ;равно 0
        out_value_l2: ;теперь bl больше 0 и не меньше 10
        mov bh, 0 ;установка верхушки bx в 0
        mov cx, 0 ;установка счетчика в 0
        out_value_m1: ;цикл
            mov dx, 0 ;обнуляем верхушку двойного слова dx:ax
            div bx ;ax / bx -> ax, ax % bx -> dx
            push dx ;заталкиваем в стек очередную цифру (dx)
            inc cx ;наращиваем счетчик
            cmp ax, 0 ;сравниваем частное от деления с нулем
        jnz out_value_m1 ;в начало цикла
        out_value_m2: ;цикл
            pop dx ;вытаскиваем из стека очередную цифру (dx)
            add dl, '0' ;корректируем код цифры в ASCII
            mov buff, dl
        
            push cx
                mov ah, 40h
                mov bx, f_Handle2
                mov cx, 1
                mov dx, offset buff 
                int 21h
            pop cx
            
            dec cx ;уменьшаем счетчик
            cmp cx, 0 ;сравниваем номер текущей цифры с нулем
        jnz out_value_m2 ;в начало цикла
        xor bl,bl
        ret ;выход из процедуры
out_value endp
CODE ENDS
  end begin
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8644 / 4479 / 1669
Регистрация: 01.02.2015
Сообщений: 13,883
Записей в блоге: 11
19.11.2017, 22:55
Вы не думаете.

На вход Str2Num должна поступать Pascal строка. А у вас заполнение символами идёт от array[1] и в процедуру передаётся array[1].
А где длина строки?
0
0 / 0 / 0
Регистрация: 02.03.2017
Сообщений: 23
19.11.2017, 23:03  [ТС]
Окей, я поправил. Переменная localcount считает количество символов и в конце докидывает в array[0] свое значение. Но от этого лучше не стало.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
DATA SEGMENT
    path db "abc.txt",0 ; имя файла для октрытия
    buf  db ?
    path2 db 'qwe.txt', 0
    f_Handle1 dw ?
    f_Handle2 dw ?
    buff db 200 dup('$')
    counter dw 0
    arraySize dw 20
    array db 6, 0, 6 dup(0)  
    indexI dw 0
    indexJ dw 0
    
    tempvar dw 0
    
    localcount db 0
DATA ENDS
 
SSEG SEGMENT STACK
      db 200 dup(?)
SSEG ENDS
 
CODE SEGMENT
 ASSUME CS:CODE, DS:DATA, SS:SSEG
  begin:
    mov ax,DATA ; настроим DS
    mov DS,ax       ; на реальный сегмент
    ;открываем файл
    mov ax,3d00h    ; открываем для чтения
    lea dx,path     ; DS:dx указатель на имя файла
    int 21h     ; в ax деcкриптор файла
    jc exit     ; если поднят флаг С, то ошибка открытия
    
    mov bx,ax       ; копируем в bx указатель файла
    xor cx,cx
    xor dx,dx
    mov ax,4200h
    int 21h     ; идем к началу файла
 
    mov si, 1
   out_str:
    mov ah,3fh      ; будем читать из файла
    mov cx,1        ; 1 байт
    lea dx,buf      ; в память buf
    int 21h        
    
    mov dl, buf
    cmp dl, '!'
    je close
 
    cmp dl, ' '
    je nextPtr
    
    mov array[si], dl
    inc si
    inc counter
    inc localcount
    
 
    nextPtr:
    cmp dl,' '
    jne out_str
    
    
    
    
    push cx
    push ax
    mov si, 0
    ;pop dl
    mov dl, localcount
    mov array[0], dl
    mov localcount,0
    
    lea si, array+1
    lea di, tempvar
    call Str2Num
    
    mov ax, tempvar
    mov cx, 10
    call Show_ax
    
    pop ax
    pop cx
    
    
    mov counter, 0
    mov si, 0
    jmp out_str
   close:           ; закрываем файл, после чтения
    mov ah,3eh
    int 21h
    
    output:
;   mov si, 0
;   mov cx, counter
;   loop1:
;       mov dl, array[si]
;       mov ah, 2
;       int 21h
;       inc si
;   loop loop1
    
   exit:            ; завершаем программу
    mov ah,4ch
    int 21h
 
Show_ax PROC
;        mov     cx, 10
        xor     di, di          ; di - кол. цифр в числе
@@Conv:
        xor     dx, dx
        div     cx              ; dl = num mod 10
        add     dl, '0'         ; перевод в символьный формат
        inc     di
        push    dx              ; складываем в стэк
        or      ax, ax
        jnz     @@conv
        ; выводим из стэка на экран
@@Show:
        pop     dx              ; dl = очередной символ
        mov     ah, 2           ; ah - функция вывода символа на экран
        int     21h
        dec     di              ; повторяем пока di<>0
        jnz     @@show
        ret
Show_ax ENDP
; CY - флаг переноса (при ошибке - установлен, иначе - сброшен)
Str2Num PROC
        push    ax
        push    bx
        push    cx
        push    dx
        push    ds
        push    es
 
        push    ds
        pop     es
 
        mov     cl, ds:[si]
        xor     ch, ch
 
        inc     si
 
        mov     bx, 10
        xor     ax, ax
 
@@Loop:
        mul     bx         ; умножаем ax на 10 ( dx:ax=ax*bx )
        mov     [di], ax   ; игнорируем старшее слово
        cmp     dx, 0      ; проверяем, результат на переполнение
        jnz     @@Error
 
        mov     al, [si]   ; Преобразуем следующий символ в число
        cmp     al, '0'
        jb      @@Error
        cmp     al, '9'
        ja      @@Error
        sub     al, '0'
        xor     ah, ah
        add     ax, [di]
        jc      @@Error    ; Если сумма больше 65535
        inc     si
 
        loop    @@Loop
 
        mov     [di], ax
        clc
        pop     es
        pop     ds
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
@@Error:
        xor     ax, ax
        mov     [di], ax
        stc
        pop     es
        pop     ds
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
Str2Num ENDP
 
out_value proc near ;выводит на экран число в ax
        cmp bl, 10 ;сравниваем с 10
            jz out_value_l1 ;если равно 10
                jc out_value_l1 ;если меньше 10
                    mov bl, 10 ;записываем в bl 10
        out_value_l1: ;теперь bl меньше либо равно 10
        cmp bl, 0 ;сравниваем с 0
            jnz out_value_l2 ;не равно 0
                mov bl, 10 ;равно 0
        out_value_l2: ;теперь bl больше 0 и не меньше 10
        mov bh, 0 ;установка верхушки bx в 0
        mov cx, 0 ;установка счетчика в 0
        out_value_m1: ;цикл
            mov dx, 0 ;обнуляем верхушку двойного слова dx:ax
            div bx ;ax / bx -> ax, ax % bx -> dx
            push dx ;заталкиваем в стек очередную цифру (dx)
            inc cx ;наращиваем счетчик
            cmp ax, 0 ;сравниваем частное от деления с нулем
        jnz out_value_m1 ;в начало цикла
        out_value_m2: ;цикл
            pop dx ;вытаскиваем из стека очередную цифру (dx)
            add dl, '0' ;корректируем код цифры в ASCII
            mov buff, dl
        
            push cx
                mov ah, 40h
                mov bx, f_Handle2
                mov cx, 1
                mov dx, offset buff 
                int 21h
            pop cx
            
            dec cx ;уменьшаем счетчик
            cmp cx, 0 ;сравниваем номер текущей цифры с нулем
        jnz out_value_m2 ;в начало цикла
        xor bl,bl
        ret ;выход из процедуры
out_value endp
CODE ENDS
  end begin
Добавлено через 2 минуты
Пробовал присваивать 48, тоже не работает. Вот код, который попроще:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
    
    mov num1[0], '3'
    mov num1[1], '1'
    mov num1[2], '2'
    mov num1[3], '4'
    
    lea     si, num1+1
    lea     di, tempvar
    call    Str2Num
    
    mov ax, tempvar
    mov cx, 10
    call Show_ax
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8644 / 4479 / 1669
Регистрация: 01.02.2015
Сообщений: 13,883
Записей в блоге: 11
19.11.2017, 23:04
А в Str2Num по прежнему передаётся array[1]...

Добавлено через 1 минуту
Чорт! Ну сделайте минимальную тестовую программу для разбора чужой процедуры!
0
0 / 0 / 0
Регистрация: 02.03.2017
Сообщений: 23
19.11.2017, 23:06  [ТС]
Ну вот, в последнем сообщении я привел простейшую прогу.
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8644 / 4479 / 1669
Регистрация: 01.02.2015
Сообщений: 13,883
Записей в блоге: 11
19.11.2017, 23:11
Так понятно
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
.model small
 
.stack 100h
 
.data
    CrLf    db  0Dh, 0Ah, '$'
    StrA    db  3, '123'
    StrB    db  4, '4567'
    wA  dw  ?
    wB  dw  ?
    wC  dw  ?
.code
 
main    proc
    mov ax,     @data
    mov ds, ax
 
    lea si, [StrA]
    lea di, [wA]
    call    Str2Num
 
    lea si, [StrB]
    lea di, [wB]
    call    Str2Num
 
    mov ax, [wA]
    add ax, [wB]
    mov [wC],   ax
 
    call    Show_AX
 
    mov ax, 4C00h
    int 21h
main    endp
 
; преобразования строки в знаковое число
; на входе:
; ds:[si] - строка с числом
; ds:[di] - адрес числа
; на выходе
; ds:[di] - число
; CY - флаг переноса (при ошибке - установлен, иначе - сброшен)
Str2Num proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    ds
        push    es
        push    si
 
        push    ds
        pop     es
 
        mov     cl, ds:[si]
        xor     ch, ch
 
        inc     si
 
        cmp     [si], byte ptr '-'
        jne     @@IsPositive
        inc     si
        dec     cx
@@IsPositive:
        jcxz    @@Error
 
        mov     bx, 10
        xor     ax, ax
 
@@Loop:
        mul     bx         ; умножаем ax на 10 ( dx:ax=ax*bx )
        mov     [di], ax   ; игнорируем старшее слово
        cmp     dx, 0      ; проверяем, результат на переполнение
        jnz     @@Error
 
        mov     al, [si]   ; Преобразуем следующий символ в число
        cmp     al, '0'
        jb      @@Error
        cmp     al, '9'
        ja      @@Error
        sub     al, '0'
        xor     ah, ah
        add     ax, [di]
        jc      @@Error    ; Если сумма больше 65535
        inc     si
 
        loop    @@Loop
 
        pop     si
        push    si
        or      ax, ax
        js      @@Error
        cmp     [si+1], byte ptr '-'
        jne     @@Positive
        neg     ax
        or      ax, ax
        jns     @@Error
@@Positive:
        mov     [di], ax
        clc
        pop     si
        pop     es
        pop     ds
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
@@Error:
        xor     ax, ax
        mov     [di], ax
        stc
        pop     si
        pop     es
        pop     ds
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
Str2Num endp
 
; выводит знаковое 16-разрядное число из регистра AX на экран
; входные данные:
; ax - число для отображения
Show_AX proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    di
 
        mov     cx,     10
        xor     di,     di  ; di - кол. цифр в числе
 
        ; если число в ax отрицательное, то
        ;1) напечатать '-'
        ;2) сделать ax положительным
        or      ax,     ax
        jns     @@Conv
        push    ax
        mov     dx,     '-'
        mov     ah,     2   ; ah - функция вывода символа на экран
        int     21h
        pop     ax
 
        neg     ax
 
@@Conv:
        xor     dx,     dx
        div     cx              ; dl = num mod 10
        add     dl,     '0'     ; перевод в символьный формат
        inc     di
        push    dx              ; складываем в стек
        or      ax,     ax
        jnz     @@Conv
        ; выводим из стека на экран
@@Show:
        pop     dx              ; dl = очередной выводимый символ
        mov     ah,     2       ; ah - функция вывода символа на экран
        int     21h
        dec     di              ; повторяем пока di<>0
        jnz     @@Show
 
        pop     di
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
Show_AX endp
 
end main
Добавлено через 1 минуту
Цитата Сообщение от Ryoma Посмотреть сообщение
Ну вот, в последнем сообщении я привел простейшую прогу.
Где передаётся длина строки в вашей проге?

А у меня она передаётся по 0-му смещению массива (строки) ds:si
0
0 / 0 / 0
Регистрация: 02.03.2017
Сообщений: 23
19.11.2017, 23:14  [ТС]
Нет, это все, конечно, очень классно и так у меня все работает. Но у меня все заполняется по индексам. Можете подкорректировать мой код, который последний кидал, маленький, чтобы все корректно работало? А то этого я понять не могу.
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8644 / 4479 / 1669
Регистрация: 01.02.2015
Сообщений: 13,883
Записей в блоге: 11
19.11.2017, 23:17
Assembler
1
2
3
4
5
6
7
8
9
10
    mov num1[0], 3 ;длина строки
    mov num1[1], '1' ; действующий символ строки
    mov num1[2], '2' ; действующий символ строки
    mov num1[3], '4' ; действующий символ строки
 
    mov num1[4], '7' ; символ строки хоть и присутствует, но из-за длины 3 не учитывается
    
    lea     si, num1
    lea     di, tempvar
    call    Str2Num
0
0 / 0 / 0
Регистрация: 02.03.2017
Сообщений: 23
19.11.2017, 23:20  [ТС]
Огромнейшее спасибо. А через переменные это можно реализовать?

Добавлено через 2 минуты
Стоп, вроде бы сам разобрался.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.11.2017, 23:20
Помогаю со студенческими работами здесь

Как считать из файла в массив типа int
Подскажите как считать из файла в массив nbgf, если есть разделитель | ifstream loader(&quot;temp.txt&quot;); if (loader.is_open()){ ...

Считать файл в переменную типа char, и работать посимвольно
считать файл в переменную типа char, а дальше с ней нужно работать посимвольно, так вот, как написать while(пока это не последний символ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru