Analysis of Answers for Assembly Language Experiment 10-1

“Assembly Language”, 3rd Edition by Wang Shuang

Chapter 10: CALL and RET Instructions

Experiment 10: Writing Subroutines (Page 206)

————————————

Note: Since Experiment 10 has three questions, and each question is more complex than previous experiments with longer code, it is divided into three articles. This is the reference answer for Question 1.

——————————-

In this experiment, we will write three subroutines to understand several common issues and master the methods to solve these problems. As with all previous experiments, this experiment must be completed independently, and the three subroutines written in this experiment will be used in subsequent courses.

1. Displaying Strings

Problem

Displaying strings is a common function in practical work, and a general subroutine should be written to implement this function. We should provide a flexible calling interface that allows the caller to decide the display position (row, column), content, and color.

Subroutine Description

Name: show_str

Function: Display a null-terminated string at a specified position with a specified color

Parameters: (dh) = row number (range 0~24),

(dl) = column number (range 0~79),

(cl) = color,

ds:si points to the starting address of the string

Returns: None

Example Application: Display the string from the data segment in green at row 8, column 3 on the screen.

assume cs:codedata segment  db 'Welcome to masm!',0data endscode segment  start: mov dh, 8         mov dl, 3         mov cl, 2           mov ax, data         mov ds, ax         mov si, 0         call show_str         mov ax, 4c00H         int 21H  show_str:             :            :            :code endsend start  

Tips

(1) The entry parameters of the subroutine are the row and column numbers on the screen. Note that they need to be converted to memory addresses within the subroutine. First, analyze the correspondence between the row and column positions on the screen and the memory addresses;

(2) Be sure to save the relevant registers used in the subroutine;

(3) The internal processing of this subroutine is closely related to the structure of video memory, but it provides an interface that is independent of the video memory structure. By calling this subroutine, one can display strings without needing to understand the structure of video memory, which facilitates programming. In the experiment, pay attention to this design philosophy.

==================

Question 1 is relatively simple, mainly requiring the use of the mul instruction when calculating the starting row and column based on the input parameters. A brief review is as follows:

mul is the multiplication instruction. This instruction has two formats:

mul reg

mul memory unit

Examples (memory units given with different addressing modes):

mul byte ptr ds:[0]

Meaning: (ax) = (al) * ((ds) * 16 + 0).

mul word ptr [bx+si+8]

Meaning: (ax) = (ax) * ((ds) * 16 + (bx) + (si) + 8) – the result’s low 16 bits.

(dx) = (ax) * ((ds) * 16 + (bx) + (si) + 8) – the result’s high 16 bits.

Implementation code reference is as follows:

;"Assembly Language", 3rd Edition by Wang Shuang; Chapter 10: CALL and RET Instructions; Experiment 10: Writing Subroutines (Page 206); 1. Displaying Strings show_str; Example Application: Display the string from the data segment in green at row 8, column 3 on the screenassume cs:codedata segment    db 'Welcome to masm!',0data endscode segment    start: mov dh, 8     ; Target row, input parameter           mov dl, 3     ; Target column, input parameter           mov cl, 2     ; Character attribute, input parameter, 2 indicates green (see Experiment 9)           mov ax, data           mov ds, ax               mov si, 0     ; ds:si as input parameter points to the string           call show_str ; Call subroutine           mov ax, 4c00H           int 21H              show_str: push es    ; Save used registers on stack              push di              push ax              mov ax, 0B800H ; Video memory segment address              mov es, ax              mov al, 160    ; One line of video memory occupies 160 bytes              mul dh         ; Calculate starting row address based on input parameter              mov di, ax     ; bp points to the starting row to display              mov al, 2      ; Character attribute placed in al, as cx will be used in the loop       s_str: mov cl, [si]   ; si default segment address ds              mov ch, 0              jcxz s_str_ok    ; Check if it is the end marker 0              mov es:[di], cl  ; Write character, cl indicates length, no need to add byte ptr              inc di              mov es:[di], al  ; Write character attribute              inc di              inc si              jmp short s_str    s_str_ok: pop ax              pop di              pop es              ret           code endsend start

Compiled and tested successfully using DOSBox, as shown in the figure below.

Since the row number 8 and column number 3 passed in as dh and dl are zero-based index values, the actual display should start from row 9, column 4.

Analysis of Answers for Assembly Language Experiment 10-1

Leave a Comment