ХАНДЫФАР

Функция ScanFormatString считывает данные из стандартного входного потока и записывает данные в местоположение, указанное аргументом. Каждый аргумент должен быть указателем на переменную типа, соответствующего спецификатору типа в формате.

Пример использования функции ScanFormatString для ввода форматированной строки в которой присутствует спецификатор .

  1. title Автор: Довгополов Евгений Сергеевич
  2. .model small
  3. .stack 100h
  4. data segment public
  5. ____askUser___db "Введите символ: \0"
  6. ____fmtoutput db "\nВы ввели: \0"
  7. ____fmtinput _db ""
  8. ____char______db ?
  9. data ends
  10. code segment public
  11. ____assume _ds:data, cs:code
  12. ____include Handyfar.inc
  13. ____main proc
  14. ________call____SetDataSegment
  15. ________lea_____ax, ds:[askUser]
  16. ________call____WriteString
  17. ________lea_____ax, ds:[char]
  18. ________push____ax
  19. ________lea_____ax, ds:[fmtinput]
  20. ________call____ScanFormatString
  21. ________add_____sp, 2
  22. ________mov_____al, char
  23. ________push____ax
  24. ________lea_____ax, ds:[fmtoutput]
  25. ________call____PrintFormatString
  26. ________add_____sp, 2
  27. ________xor_____al, al
  28. ________call____ExitProcess
  29. ____main endp
  30. code ends
  31. end main
Функция ScanFormatString считывает данные из стандартного входного потока и записывает данные в местоположение, указанное аргументом. Каждый аргумент должен быть указателем на переменную типа, соответствующего спецификатору типа в формате.

Пример использования функции ScanFormatString для ввода форматированной строки в которой присутствует спецификатор .

  1. title Автор: Довгополов Евгений Сергеевич
  2. .model small
  3. .stack 100h
  4. data segment public
  5. ____askUser___db "Введите символ: \0"
  6. ____fmtoutput db "\nВы ввели: \0"
  7. ____fmtinput _db ""
  8. ____char______db ?
  9. data ends
  10. code segment public ________________; Начало сегмента кода
  11. ____assume _ds:data, cs:code
  12. ____include Handyfar.inc____________; Подключаем файл с функциями
  13. ____main proc ______________________; Начало процедуры main
  14. ________call____SetDataSegment______; Вызываем процедуру SetDataSegment
  15. ________lea_____ax, ds:[askUser]____; Загружаем адрес переменной askUser в регистр ds:ax
  16. ________call____WriteString_________; Вызываем процедуру WriteString(ax:askUser)
  17. ________lea_____ax, ds:[char]_______; Загружаем адрес переменной char в регистр ds:ax
  18. ________push____ax__________________; 2-й: Сохраняем значение регистра ax в стеке
  19. ________lea_____ax, ds:[fmtinput]___; 1-й: Загружаем адрес строки формата fmtinput в регистр ds:ax
  20. ________call____ScanFormatString____; Вызываем процедуру ScanFormatString(ax:fmtinput, char)
  21. ________add_____sp, 2_______________; Выравниваем стек
  22. ________mov_____al, char____________; Копируем значение переменной char в регистр al
  23. ________push____ax________________—_; 2-й: Сохраняем значение регистра ax в стеке
  24. ________lea_____ax, ds:[fmtoutput]__; 1-й: Загружаем адрес строки формата fmtoutput в регистр ds:ax
  25. ________call____PrintFormatString_—_; Вызываем процедуру PrintFormatString(ax:fmtoutput, char)
  26. ________add_____sp, 2_______________; Выравниваем стек
  27. ________xor_____al, al______________; Обнуляем регистр al
  28. ________call____ExitProcess_________; Вызываем процедуру ExitProcess
  29. ____main endp ______________________; Конец процедуры main
  30. code ends __________________________; Конец сегмента кода
  31. end main ___________________________; Конец файла. Точкой входа указывается процедура main
Пример использования функции ScanFormatString для ввода форматированной строки в которой присутствует спецификатор %s.

  1. title Автор: Довгополов Евгений Сергеевич
  2. .model small
  3. .stack 100h
  4. data segment public
  5. ____askUser ____db "Введите свое полное ___________________имя: \0"
  6. ____fmtoutput __db "\nВаше полное имя %s ___________________%s %s\0"
  7. ____fmtinput ___db "%s %s %s"
  8. ____first_name _db 20 dup(0)
  9. ____middle_name db 20 dup(0)
  10. ____last_name __db 20 dup(0)
  11. data ends
  12. code segment public
  13. ____assume _ds:data, cs:code
  14. ____include Handyfar.inc
  15. ____main proc
  16. ________call____SetDataSegment
  17. ________lea_____ax, ds:[askUser]
  18. ________call____WriteString
  19. ________lea_____ax, ds:[middle_name]
  20. ________push____ax
  21. ________lea_____ax, ds:[first_name]
  22. ________push____ax
  23. ________lea_____ax, ds:[last_name]
  24. ________push____ax
  25. ________lea_____ax, ds:[fmtinput]
  26. ________call____ScanFormatString
  27. ________add_____sp, 6
  28. ________lea_____ax, ds:[middle_name]
  29. ________push____ax
  30. ________lea_____ax, ds:[first_name]
  31. ________push____ax
  32. ________lea_____ax, ds:[last_name]
  33. ________push____ax
  34. ________lea_____ax, ds:[fmtoutput]
  35. ________call____PrintFormatString
  36. ________add_____sp, 6
  37. ________xor_____al, al
  38. ________call____ExitProcess
  39. ____main endp
  40. code ends
  41. end main
Пример использования функции ScanFormatString для ввода форматированной строки в которой присутствует спецификатор %s.

  1. title Автор: Довгополов Евгений Сергеевич
  2. .model small
  3. .stack 100h
  4. data segment public
  5. ____askUser ____db "Введите свое полное имя: \0"
  6. ____fmtoutput __db "\nВаше полное имя %s %s %s\0"
  7. ____fmtinput ___db "%s %s %s"
  8. ____first_name _db 20 dup(0)
  9. ____middle_name db 20 dup(0)
  10. ____last_name __db 20 dup(0)
  11. data ends
  12. code segment public __________________; Начало сегмента кода
  13. ____assume _ds:data, cs:code
  14. ____include Handyfar.inc______________; Подключаем файл с функциями
  15. ____main proc ________________________; Начало процедуры main
  16. ________call____SetDataSegment________; Вызываем процедуру SetDataSegment
  17. ________lea_____ax, ds:[askUser]______; Загружаем адрес переменной askUser в регистр ds:ax
  18. ________call____WriteString___________; Вызываем процедуру WriteString(ax:askUser)
  19. ________lea_____ax, ds:[middle_name]__; Загружаем адрес переменной middle_name в регистр ds:ax
  20. ________push____ax____________________; 4-й: Сохраняем значение регистра ax в стеке
  21. ________lea_____ax, ds:[first_name]___; Загружаем адрес переменной first_name в регистр ds:ax
  22. ________push____ax____________________; 3-й: Сохраняем значение регистра ax в стеке
  23. ________lea_____ax, ds:[last_name]____; Загружаем адрес переменной last_name в регистр ds:ax
  24. ________push____ax____________________; 2-й: Сохраняем значение регистра ax в стеке
  25. ________lea_____ax, ds:[fmtinput]_____; 1-й: Загружаем адрес строки формата fmtinput в регистр ds:ax
  26. ________call____ScanFormatString______; Вызываем процедуру ScanFormatString(ax:fmtinput, ...)
  27. ________add_____sp, 6_________________; Выравниваем стек
  28. ________lea_____ax, ds:[middle_name]__; Загружаем адрес переменной middle_name в регистр ds:ax
  29. ________push____ax____________________; 4-й: Сохраняем значение регистра ax в стеке
  30. ________lea_____ax, ds:[first_name]___; Загружаем адрес переменной first_name в регистр ds:ax
  31. ________push____ax____________________; 3-й: Сохраняем значение регистра ax в стеке
  32. ________lea_____ax, ds:[last_name]____; Загружаем адрес переменной last_name в регистр ds:ax
  33. ________push____ax____________________; 2-й: Сохраняем значение регистра ax в стеке
  34. ________lea_____ax, ds:[fmtoutput]____; 1-й: Загружаем адрес строки формата fmtoutput в регистр ds:ax
  35. ________call____PrintFormatString_—___; Вызываем процедуру PrintFormatString(ax:fmtoutput, ...)
  36. ________add_____sp, 6_________________; Выравниваем стек
  37. ________xor_____al, al________________; Обнуляем регистр al
  38. ________call____ExitProcess___________; Вызываем процедуру ExitProcess
  39. ____main endp ________________________; Конец процедуры main
  40. code ends ____________________________; Конец сегмента кода
  41. end main _____________________________; Конец файла. Точкой входа указывается процедура main
Для того чтобы считать несколько слов в один буффер необходимо спользовать символ (&), который переводится с английского как (и).

  1. title Автор: Довгополов Евгений Сергеевич
  2. .model small
  3. .stack 100h
  4. data segment public
  5. ____askUser __db "Введите свое полное _________________имя: \0"
  6. ____fmtoutput db "\nВаше полное имя %s\0"
  7. ____fmtinput _db "%s"
  8. ____full_name db 50 dup(0)
  9. data ends
  10. code segment public
  11. ____assume _ds:data, cs:code
  12. ____include Handyfar.inc
  13. ____main proc
  14. ________call____SetDataSegment
  15. ________lea_____ax, ds:[askUser]
  16. ________call____WriteString
  17. ________lea_____ax, ds:[full_name]
  18. ________push____ax
  19. ________lea_____ax, ds:[fmtinput]
  20. ________call____ScanFormatString
  21. ________add_____sp, 2
  22. ________lea_____ax, ds:[full_name]
  23. ________push____ax
  24. ________lea_____ax, ds:[fmtoutput]
  25. ________call____PrintFormatString
  26. ________add_____sp, 2
  27. ________xor_____al, al
  28. ________call____ExitProcess
  29. ____main endp
  30. code ends
  31. end main
Для того чтобы считать несколько слов в один буффер необходимо спользовать символ (&), который переводится с английского как (и).

  1. title Автор: Довгополов Евгений Сергеевич
  2. .model small
  3. .stack 100h
  4. data segment public
  5. ____askUser __db "Введите свое полное имя: \0"
  6. ____fmtoutput db "\nВаше полное имя %s\0"
  7. ____fmtinput _db "%s"
  8. ____full_name db 50 dup(0)
  9. data ends
  10. code segment public ________________; Начало сегмента кода
  11. ____assume _ds:data, cs:code
  12. ____include Handyfar.inc____________; Подключаем файл с функциями
  13. ____main proc ______________________; Начало процедуры main
  14. ________call____SetDataSegment______; Вызываем процедуру SetDataSegment
  15. ________lea_____ax, ds:[askUser]____; Загружаем адрес переменной askUser в регистр ds:ax
  16. ________call____WriteString_________; Вызываем процедуру WriteString(ax:askUser)
  17. ________lea_____ax, ds:[full_name]__; Загружаем адрес переменной full_name в регистр ds:ax
  18. ________push____ax__________________; 2-й: Сохраняем значение регистра ax в стеке
  19. ________lea_____ax, ds:[fmtinput]___; 1-й: Загружаем адрес строки формата fmtinput в регистр ds:ax
  20. ________call____ScanFormatString____; Вызываем процедуру ScanFormatString(ax:fmtinput, full_name)
  21. ________add_____sp, 2_______________; Выравниваем стек
  22. ________lea_____ax, ds:[full_name]__; Загружаем адрес переменной full_name в регистр ds:ax
  23. ________push____ax__________________; 2-й: Сохраняем значение регистра ax в стеке
  24. ________lea_____ax, ds:[fmtoutput]__; 1-й: Загружаем адрес строки формата fmtoutput в регистр ds:ax
  25. ________call____PrintFormatString_—_; Вызываем процедуру PrintFormatString(ax:fmtoutput, full_name)
  26. ________add_____sp, 2_______________; Выравниваем стек
  27. ________xor_____al, al______________; Обнуляем регистр al
  28. ________call____ExitProcess_________; Вызываем процедуру ExitProcess
  29. ____main endp ______________________; Конец процедуры main
  30. code ends __________________________; Конец сегмента кода
  31. end main ___________________________; Конец файла. Точкой входа указывается процедура main
Пример использования функции ScanFormatString для ввода форматированной строки в которой присутствует спецификатор %s, %c, %. и %d.

  1. title Автор: Довгополов Евгений Сергеевич
  2. .model small
  3. .stack 100h
  4. data segment public
  5. ____askUser __db "Введите свое имя, пол и _________________возраст: \0"
  6. ____fmtoutput db "ИМЯ: %.4s\nПОЛ: _________________%.4c\nВОЗРАСТ: %d\0"
  7. ____fmtinput _db "%s %c %d"
  8. ____user_name db 20 dup(0)
  9. ____user_sex _db ?
  10. ____user_age _dw ?
  11. data ends
  12. code segment public
  13. ____assume _ds:data, cs:code
  14. ____include Handyfar.inc
  15. ____main proc
  16. ________call____SetDataSegment
  17. ________lea_____ax, ds:[askUser]
  18. ________call____WriteString
  19. ________lea_____ax, ds:[user_age]
  20. ________push____ax
  21. ________lea_____ax, ds:[user_sex]
  22. ________push____ax
  23. ________lea_____ax, ds:[user_name]
  24. ________push____ax
  25. ________lea_____ax, ds:[fmtinput]
  26. ________call____ScanFormatString
  27. ________add_____sp, 6
  28. ________call____ClearScreen_
  29. ________push____user_age
  30. ________mov_____al, user_sex
  31. ________call____ToUpperChar
  32. ________push____ax
  33. ________lea_____ax, ds:[user_name]
  34. ________call____ToUpperString
  35. ________push____ax
  36. ________lea_____ax, ds:[fmtoutput]
  37. ________call____PrintFormatString
  38. ________add_____sp, 6
  39. ________xor_____al, al
  40. ________call____ExitProcess
  41. ____main endp
  42. code ends
  43. end main
Пример использования функции ScanFormatString для ввода форматированной строки в которой присутствует спецификатор %s, %c, %. и %d.

  1. title Автор: Довгополов Евгений Сергеевич
  2. .model small
  3. .stack 100h
  4. data segment public
  5. ____askUser __db "Введите свое имя, пол и возраст: \0"
  6. ____fmtoutput db "ИМЯ: %.4s\nПОЛ: %.4c\nВОЗРАСТ: %d\0"
  7. ____fmtinput _db "%s %c %d"
  8. ____user_name db 20 dup(0)
  9. ____user_sex _db ?
  10. ____user_age _dw ?
  11. data ends
  12. code segment public ________________; Начало сегмента кода
  13. ____assume _ds:data, cs:code
  14. ____include Handyfar.inc____________; Подключаем файл с функциями
  15. ____main proc ______________________; Начало процедуры main
  16. ________call____SetDataSegment______; Вызываем процедуру SetDataSegment
  17. ________lea_____ax, ds:[askUser]____; Загружаем адрес переменной askUser в регистр ds:ax
  18. ________call____WriteString_________; Вызываем процедуру WriteString(ax:askUser)
  19. ________lea_____ax, ds:[user_age]___; Загружаем адрес переменной user_age в регистр ds:ax
  20. ________push____ax__________________; 4-й: Сохраняем значение регистра ax в стеке
  21. ________lea_____ax, ds:[user_sex]___; Загружаем адрес переменной user_sex в регистр ds:ax
  22. ________push____ax__________________; 3-й: Сохраняем значение регистра ax в стеке
  23. ________lea_____ax, ds:[user_name]__; Загружаем адрес переменной user_name в регистр ds:ax
  24. ________push____ax__________________; 2-й: Сохраняем значение регистра ax в стеке
  25. ________lea_____ax, ds:[fmtinput]___; 1-й: Загружаем адрес строки формата fmtinput в регистр ds:ax
  26. ________call____ScanFormatString____; Вызываем процедуру ScanFormatString(ax:fmtinput, ...)
  27. ________add_____sp, 6_______________; Выравниваем стек
  28. ________call____ClearScreen_________; Вызываем процедуру ClearScreen для отчистки экрана
  29. ________push____user_age____________; 4-й: Сохраняем значение переменной user_age в стеке
  30. ________mov_____al, user_sex________; Копируем значение переменной user_sex в регистр al
  31. ________call____ToUpperChar_________; Вызываем процедуру ToUpperChar(al:user_sex)
  32. ________push____ax__________________; 3-й: Сохраняем значение регистра ax в стеке
  33. ________lea_____ax, ds:[user_name]__; Загружаем адрес переменной user_name в регистр ds:ax
  34. ________call____ToUpperString_______; Вызываем процедуру ToUpperString(ax:user_name)
  35. ________push____ax__________________; 2-й: Сохраняем значение регистра ax в стеке
  36. ________lea_____ax, ds:[fmtoutput]__; 1-й: Загружаем адрес строки формата fmtoutput в регистр ds:ax
  37. ________call____PrintFormatString_—_; Вызываем процедуру PrintFormatString(ax:fmtoutput, ...)
  38. ________add_____sp, 6_______________; Выравниваем стек
  39. ________xor_____al, al______________; Обнуляем регистр al
  40. ________call____ExitProcess_________; Вызываем процедуру ExitProcess
  41. ____main endp ______________________; Конец процедуры main
  42. code ends __________________________; Конец сегмента кода
  43. end main ___________________________; Конец файла. Точкой входа указывается процедура main
Функция ScanFormatString распознает не только спецификаторы но и текст в качестве формата. В следующем примере пользователю нужно ввести не только имя но и то, что указанно перед спецификатором %s. Если условия не будут выполнены, то результат будет неправильным.

  1. title Автор: Довгополов Евгений Сергеевич
  2. .model small
  3. .stack 100h
  4. data segment public
  5. ____askUser __db "Введите свое имя: \0"
  6. ____fmtoutput db "\nВаше имя %s\0"
  7. ____fmtinput _db "Меня зовут %s"
  8. ____user_name db 20 dup(0)
  9. data ends
  10. code segment public
  11. ____assume _ds:data, cs:code
  12. ____include Handyfar.inc
  13. ____main proc
  14. ________call____SetDataSegment
  15. ________lea_____ax, ds:[askUser]
  16. ________call____WriteString
  17. ________lea_____ax, ds:[user_name]
  18. ________push____ax
  19. ________lea_____ax, ds:[fmtinput]
  20. ________call____ScanFormatString
  21. ________add_____sp, 2
  22. ________lea_____ax, ds:[user_name]
  23. ________push____ax
  24. ________lea_____ax, ds:[fmtoutput]
  25. ________call____PrintFormatString
  26. ________add_____sp, 2
  27. ________xor_____al, al
  28. ________call____ExitProcess
  29. ____main endp
  30. code ends
  31. end main
Функция ScanFormatString распознает не только спецификаторы но и текст в качестве формата. В следующем примере пользователю нужно ввести не только имя но и то, что указанно перед спецификатором %s. Если условия не будут выполнены, то результат будет неправильным.

  1. title Автор: Довгополов Евгений Сергеевич
  2. .model small
  3. .stack 100h
  4. data segment public
  5. ____askUser __db "Введите свое имя: \0"
  6. ____fmtoutput db "\nВаше имя %s\0"
  7. ____fmtinput _db "Меня зовут %s"
  8. ____user_name db 20 dup(0)
  9. data ends
  10. code segment public ________________; Начало сегмента кода
  11. ____assume _ds:data, cs:code
  12. ____include Handyfar.inc____________; Подключаем файл с функциями
  13. ____main proc ______________________; Начало процедуры main
  14. ________call____SetDataSegment______; Вызываем процедуру SetDataSegment
  15. ________lea_____ax, ds:[askUser]____; Загружаем адрес переменной askUser в регистр ds:ax
  16. ________call____WriteString_________; Вызываем процедуру WriteString(ax:askUser)
  17. ________lea_____ax, ds:[user_name]__; Загружаем адрес переменной user_name в регистр ds:ax
  18. ________push____ax__________________; 2-й: Сохраняем значение регистра ax в стеке
  19. ________lea_____ax, ds:[fmtinput]___; 1-й: Загружаем адрес строки формата fmtinput в регистр ds:ax
  20. ________call____ScanFormatString____; Вызываем процедуру ScanFormatString(ax:fmtinput, user_name)
  21. ________add_____sp, 2_______________; Выравниваем стек
  22. ________lea_____ax, ds:[user_name]__; Загружаем адрес переменной user_name в регистр ds:ax
  23. ________push____ax__________________; 2-й: Сохраняем значение регистра ax в стеке
  24. ________lea_____ax, ds:[fmtoutput]__; 1-й: Загружаем адрес строки формата fmtoutput в регистр ds:ax
  25. ________call____PrintFormatString_—_; Вызываем процедуру PrintFormatString(ax:fmtoutput, user_name)
  26. ________add_____sp, 2_______________; Выравниваем стек
  27. ________xor_____al, al______________; Обнуляем регистр al
  28. ________call____ExitProcess_________; Вызываем процедуру ExitProcess
  29. ____main endp ______________________; Конец процедуры main
  30. code ends __________________________; Конец сегмента кода
  31. end main ___________________________; Конец файла. Точкой входа указывается процедура main
Вот более сложный но практичный пример работы со структурой PERSON. В данном примере мы создадим функции сеттеры и геттеры для записи данных в структуру и для взятия данных из структуры.

  1. title Автор: Довгополов Евгений Сергеевич
  2. .model small
  3. .stack 100h
  4. PERSON struc
  5. ____m_name ___db 20 dup(0)
  6. ____m_surname db 20 dup(0)
  7. ____m_age ____dw ?
  8. PERSON ends
  9. data segment public
  10. ____EVGENII PERSON <>
  11. ____SERGEII PERSON <>
  12. data ends
  13. data segment public
  14. ____u_name ___db "Введите своё имя: \0"
  15. ____u_surname db "\nВведите свою фамилию: _________________\0"
  16. ____u_age ____db "\nВведите свой возраст: _________________\0"
  17. ____fmtstr ___db "\n\nИмя: %.4s\nФамилия: _________________%s\nВозраст: %d\n\0"
  18. data ends
  19. code segment public
  20. ____assume _ds:data, cs:code
  21. ____include Handyfar.inc
  22. ____main proc
  23. ________call____SetDataSegment
  24. ________lea_____si, ds:[EVGENII]
  25. ________lea_____ax, ds:[u_name]
  26. ________call____WriteString
  27. ________call____SetPersonName
  28. ________lea_____ax, ds:[u_surname]
  29. ________call____WriteString
  30. ________call____SetPersonSurname
  31. ________lea_____ax, ds:[u_age]
  32. ________call____WriteString
  33. ________call____SetPersonAge
  34. ________call____GetPersonAge
  35. ________push____ax
  36. ________call____GetPersonSurname
  37. ________push____ax
  38. ________call____GetPersonName
  39. ________push____ax
  40. ________lea_____ax, ds:[fmtstr]
  41. ________call____PrintFormatString
  42. ________add_____sp, 6
  43. ________call____PrintNewLine
  44. ________lea_____si, ds:[SERGEII]
  45. ________lea_____ax, ds:[u_name]
  46. ________call____WriteString
  47. ________call____SetPersonName
  48. ________lea_____ax, ds:[u_surname]
  49. ________call____WriteString
  50. ________call____SetPersonSurname
  51. ________lea_____ax, ds:[u_age]
  52. ________call____WriteString
  53. ________call____SetPersonAge
  54. ________call____GetPersonAge
  55. ________push____ax
  56. ________call____GetPersonSurname
  57. ________push____ax
  58. ________call____GetPersonName
  59. ________push____ax
  60. ________lea_____ax, ds:[fmtstr]
  61. ________call____PrintFormatString
  62. ________add_____sp, 6
  63. ________xor_____al, al
  64. ________call____ExitProcess
  65. ____main endp
  66. ____SetPersonName proc
  67. ________push____ax
  68. ________push____si
  69. ____data segment
  70. ________set_name db "%s", 0
  71. ____data ends
  72. ________lea_____ax, [si].m_name
  73. ________push____ax
  74. ________lea_____ax, ds:[set_name]
  75. ________call____ScanFormatString
  76. ________add_____sp, 2
  77. ________pop_____si
  78. ________pop_____ax
  79. ________ret
  80. ____SetPersonName endp
  81. ____SetPersonSurname proc
  82. ________push____ax
  83. ________push____si
  84. ____data segment
  85. ________set_surname db "%s", 0
  86. ____data ends
  87. ________lea_____ax, [si].m_surname
  88. ________push____ax
  89. ________lea_____ax, ds:[set_surname]
  90. ________call____ScanFormatString
  91. ________add_____sp, 2
  92. ________pop_____si
  93. ________pop_____ax
  94. ________ret
  95. ____SetPersonSurname endp
  96. ____SetPersonAge proc
  97. ________push____ax
  98. ________push____si
  99. ____data segment
  100. ________set_age db "%d", 0
  101. ____data ends
  102. ________lea_____ax, [si].m_age
  103. ________push____ax
  104. ________lea_____ax, ds:[set_age]
  105. ________call____ScanFormatString
  106. ________add_____sp, 2
  107. ________pop_____si
  108. ________pop_____ax
  109. ________ret
  110. ____SetPersonAge endp
  111. ____GetPersonName proc
  112. ________lea_____ax, [si].m_name
  113. ________ret
  114. ____GetPersonName endp
  115. ____GetPersonSurname proc
  116. ________lea_____ax, [si].m_surname
  117. ________ret
  118. ____GetPersonSurname endp
  119. ____GetPersonAge proc
  120. ________lea_____ax, [si].m_age
  121. ________ret
  122. ____GetPersonAge endp
  123. code ends
  124. end main
Вот более сложный но практичный пример работы со структурой PERSON. В данном примере мы создадим функции сеттеры и геттеры для записи данных в структуру и для взятия данных из структуры.

  1. title Автор: Довгополов Евгений Сергеевич
  2. .model small
  3. .stack 100h
  4. PERSON struc
  5. ____m_name ___db 20 dup(0)
  6. ____m_surname db 20 dup(0)
  7. ____m_age ____dw ?
  8. PERSON ends
  9. data segment public
  10. ____EVGENII PERSON <>
  11. ____SERGEII PERSON <>
  12. data ends
  13. data segment public
  14. ____u_name ___db "Введите своё имя: \0"
  15. ____u_surname db "\nВведите свою фамилию: \0"
  16. ____u_age ____db "\nВведите свой возраст: \0"
  17. ____fmtstr ___db "\n\nИмя: %.4s\nФамилия: %s\nВозраст: %d\n\0"
  18. data ends
  19. code segment public __________________; Начало сегмента кода
  20. ____assume _ds:data, cs:code
  21. ____include Handyfar.inc______________; Подключаем файл с функциями
  22. ____main proc ________________________; Начало процедуры main
  23. ________call____SetDataSegment________; Вызываем процедуру SetDataSegment
  24. ________lea_____si, ds:[EVGENII]______; Загружаем адрес EVGENII в ds:si
  25. ________lea_____ax, ds:[u_name]_______; Загружаем адрес переменной u_name в регистр ds:ax
  26. ________call____WriteString___________; Вызываем процедуру WriteString(ax:u_name)
  27. ________call____SetPersonName_________; Вызываем SetPersonName(si)
  28. ________lea_____ax, ds:[u_surname]____; Загружаем адрес переменной u_surname в регистр ds:ax
  29. ________call____WriteString___________; Вызываем процедуру WriteString(ax:u_surname)
  30. ________call____SetPersonSurname______; Вызываем SetPersonSurname(si)
  31. ________lea_____ax, ds:[u_age]________; Загружаем адрес переменной u_age в регистр ds:ax
  32. ________call____WriteString___________; Вызываем процедуру WriteString(ax:u_age)
  33. ________call____SetPersonAge__________; Вызываем SetPersonAge(si)
  34. ________call____GetPersonAge__________; Вызываем GetPersonAge() := AX
  35. ________push____ax____________________; 4-й: Сохраняем значение регистра ax в стеке
  36. ________call____GetPersonSurname______; Вызываем GetPersonSurname() := AX
  37. ________push____ax____________________; 3-й: Сохраняем значение регистра ax в стеке
  38. ________call____GetPersonName_________; Вызываем GetPersonName() := AX
  39. ________push____ax____________________; 2-й: Сохраняем значение регистра ax в стеке
  40. ________lea_____ax, ds:[fmtstr]_______; 1-й: Загружаем адрес строки формата fmtstr в регистр
  41. ________call____PrintFormatString_—___; Вызываем процедуру PrintFormatString(ax:fmtstr, ...)
  42. ________add_____sp, 6_________________; Выравниваем стек
  43. ________call____PrintNewLine
  44. ________lea_____si, ds:[SERGEII]______; Загружаем адрес SERGEII в ds:si
  45. ________lea_____ax, ds:[u_name]_______; Загружаем адрес переменной u_name в регистр ds:ax
  46. ________call____WriteString___________; Вызываем процедуру WriteString(ax:u_name)
  47. ________call____SetPersonName_________; Вызываем SetPersonName(si)
  48. ________lea_____ax, ds:[u_surname]____; Загружаем адрес переменной u_surname в регистр ds:ax
  49. ________call____WriteString___________; Вызываем процедуру WriteString(ax:u_surname)
  50. ________call____SetPersonSurname______; Вызываем SetPersonSurname(si)
  51. ________lea_____ax, ds:[u_age]________; Загружаем адрес переменной u_age в регистр ds:ax
  52. ________call____WriteString___________; Вызываем процедуру WriteString(ax:u_age)
  53. ________call____SetPersonAge__________; Вызываем SetPersonAge(si)
  54. ________call____GetPersonAge__________; Вызываем GetPersonAge() := AX
  55. ________push____ax____________________; 4-й: Сохраняем значение регистра ax в стеке
  56. ________call____GetPersonSurname______; Вызываем GetPersonSurname() := AX
  57. ________push____ax____________________; 3-й: Сохраняем значение регистра ax в стеке
  58. ________call____GetPersonName_________; Вызываем GetPersonName() := AX
  59. ________push____ax____________________; 2-й: Сохраняем значение регистра ax в стеке
  60. ________lea_____ax, ds:[fmtstr]_______; 1-й: Загружаем адрес строки формата fmtstr в регистр ds:ax
  61. ________call____PrintFormatString_—___; Вызываем процедуру PrintFormatString(ax:fmtstr, ...)
  62. ________add_____sp, 6_________________; Выравниваем стек
  63. ________xor_____al, al________________; Обнуляем регистр al
  64. ________call____ExitProcess___________; Вызываем процедуру ExitProcess
  65. ____main endp ________________________; Конец процедуры main
  66. ____SetPersonName proc________________; Начало процедуры SetPersonName
  67. ________push____ax
  68. ________push____si
  69. ____data segment
  70. ________set_name db "%s", 0
  71. ____data ends
  72. ________lea_____ax, [si].m_name_______; Загружаем адрес переменной m_name в регистр ds:ax
  73. ________push____ax____________________; 2-й: Сохраняем значение регистра ax в стеке
  74. ________lea_____ax, ds:[set_name]_____; 1-й: Загружаем адрес строки формата set_name в регистр ds:ax
  75. ________call____ScanFormatString______; Вызываем процедуру ScanFormatString(ax:set_name, ...)
  76. ________add_____sp, 2_________________; Выравниваем стек
  77. ________pop_____si
  78. ________pop_____ax
  79. ________ret___________________________; Возврат из процедуры
  80. ____SetPersonName endp________________; Конец процедуры SetPersonName
  81. ____SetPersonSurname proc_____________; Начало процедуры SetPersonSurname
  82. ________push____ax
  83. ________push____si
  84. ____data segment
  85. ________set_surname db "%s", 0
  86. ____data ends
  87. ________lea_____ax, [si].m_surname____; Загружаем адрес переменной m_surname в регистр ds:ax
  88. ________push____ax____________________; 2-й: Сохраняем значение регистра ax в стеке
  89. ________lea_____ax, ds:[set_surname]__; 1-й: Загружаем адрес строки формата set_surname в ds:ax
  90. ________call____ScanFormatString______; Вызываем процедуру ScanFormatString(ax:set_surname, ...)
  91. ________add_____sp, 2_________________; Выравниваем стек
  92. ________pop_____si
  93. ________pop_____ax
  94. ________ret___________________________; Возврат из процедуры
  95. ____SetPersonSurname endp_____________; Конец процедуры SetPersonSurname
  96. ____SetPersonAge proc_________________; Начало процедуры SetPersonAge
  97. ________push____ax
  98. ________push____si
  99. ____data segment
  100. ________set_age db "%d", 0
  101. ____data ends
  102. ________lea_____ax, [si].m_age________; Загружаем адрес переменной m_age в регистр ds:ax
  103. ________push____ax____________________; 2-й: Сохраняем значение регистра ax в стеке
  104. ________lea_____ax, ds:[set_age]______; 1-й: Загружаем адрес строки формата set_age в регистр ds:ax
  105. ________call____ScanFormatString______; Вызываем процедуру ScanFormatString(ax:set_age, ...)
  106. ________add_____sp, 2_________________; Выравниваем стек
  107. ________pop_____si
  108. ________pop_____ax
  109. ________ret___________________________; Возврат из процедуры
  110. ____SetPersonAge endp_________________; Конец процедуры SetPersonAge
  111. ____GetPersonName proc________________; Начало процедуры GetPersonName
  112. ________lea_____ax, [si].m_name_______; Загружаем адрес [si].m_name в регистр ax
  113. ________ret___________________________; Возврат из процедуры
  114. ____GetPersonName endp________________; Конец процедуры GetPersonName
  115. ____GetPersonSurname proc_____________; Начало процедуры GetPersonSurname
  116. ________lea_____ax, [si].m_surname____; Загружаем адрес [si].m_surname в регистр ax
  117. ________ret___________________________; Возврат из процедуры
  118. ____GetPersonSurname endp_____________; Конец процедуры GetPersonSurname
  119. ____GetPersonAge proc_________________; Начало процедуры GetPersonAge
  120. ________lea_____ax, [si].m_age________; Загружаем адрес [si].m_age в регистр ax
  121. ________ret___________________________; Возврат из процедуры
  122. ____GetPersonAge endp_________________; Конец процедуры GetPersonAge
  123. code ends ____________________________; Конец сегмента кода
  124. end main _____________________________; Конец файла. Точкой входа указывается процедура main
Made on
Tilda