(Задание 02 курса Assembly Language)
The objective of this assignment is to write a C and assembly mixed-mode program which accepts a simulated bit pattern, which represent ASCII characters which are HEX digits. Thus the bit pattern 0011100101000001 would represent the ASCII codes for the HEX digits 9A. You are to discard invalid HEX digits. The assignment is to be done as outlined below. The C main function inputs a relatively small integer “n”. The variable “n” is the number of characters to be read and should be small. It then passes by value the parameter “n” , and a pointer to an array “string” to an assembly language procedure. Upon the return from the procedure the main C function outputs the string in the array “string”. The assembly language procedure reads a serial string of simulated incoming “bits” ( simulated by typing ASCII 0’s and 1’s) and packs them into bytes eight at a time.There are exactly n ASCII characters or 8n “bits”. The assembly procedure then passes the byte to a C function which determines if the byte is a valid ASCII HEX digit ( namely 0-F). If the byte is a valid ASCII HEX digit, it stores the digit into the array up to a maximum of “n” characters. If the byte is invalid no action is taken and it goes on to the next group of bits. After the bits have been read in it then stores a null character into the array and returns to the main function. Assume that you will type in exact multiples of 8 bits so that you do NOT have to check if the number of “bits” is a multiple of 8. In the assembly function, use int 21H for the I/O. Do not use io.mac. It is a good idea to have the “bits” read from a file.
The second “called” C function checks if the byte passed to it as a char is a valid HEX digit. It returns a 1 if it is and prints the character otherwise it prints ” NOT A DIGIT” and returns a 0. e.g. if the simulated bit stream is 001101110100110101000010 then the output look like 7 NOT A DIGIT A 7A NOTE: Keep the n value small so that you dont have to type more then 3 or 4 characters at a time. NOTE: Your program should strictly follow the specifications given here. Also, make sure to submit enough evidence that indicates that you have thoroughly tested your program.
NOTE: The DOS command in the c: drive > bcc my_c_file.c my_assembly_file.asm will compile the c code, assemble the assembly code and link the files. The file with the starting function should be first. Note; You should probably avoid the macro’s. Use int 21H. for I/O in the assembly code. The integer n is read in the c code . Submit the following files using Raven: 1.The source code. Make a backup of everything on a disk in case of problems with Raven. 2.Test plan and test data output: For each test case, provide the objective (why you are doing that particular test) and the rationale for selecting the test input. Zero marks will be given to this part if your assignment provides testing information without this information (i.e., objective and rationale). In particular identify the border cases and test them. Marking scheme for this assignment (25 marks): Correctness of the program: 15 marks (if your programs works correctly and your documentation convinces the TA – don’t expect marks if you just submit a print out of the source code) Structure and comments: 4 marks (general quality,spacing, indentation, comments, variable names etc.) Test plan & test data output: 6 marks (zero marks if no objective and rationale as mentioned above)
Solution
assign3_asm_part.asm
TITLE Assignment 3 COMMENT | The objective of this assignment is to write a C and assembly mixed-mode program which accepts a simulated bit pattern, which represent ASCII characters which are HEX digits. | .MODEL SMALL EXTRN C chk:PROC .DATA ; we don't really need any data here .CODE .486 PUBLIC C input input PROC ARG num:WORD, \ str:PTR WORD ; set argument addresses to simple names push BP mov BP, SP ; prepares pointers push SI ; stores SI, DI register values push DI mov DI, [str] ; DI := address of string mov CX, [num] ; CX := number of bytes to get work_on_byte: mov SI, 0 ; clear SI for use push CX ; push outer loop count mov CX, BITS ; make inner loop count to read BITS work_on_bit: mov AH, 8 ; interrupt input, input hidden as typed int 21h cmp AL, 1 ; compare input to ONE label je one ; if same input is equal to ONE label shl SI, 1 ; shift SI bits left jmp next ; jump to next because input was 0 one: shl SI, 1 ; shift SI bits left or SI, 0001h ; insert bit of 1 next: loop get_bits ; loop bits call check_bits C, SI; 8 bits have been typed, send BYTE to get checked cmp AX, 1 ; compare return value to 1 je good_char ; if return 1, value is good, value is put in array jmp next_bits ; if return 0, check next input byte, or exit good_char: mov [DI], SI ; put BYTE in array add DI, 1 ; shift to next array postiton next_bits: pop CX ; pop counter CX for outside loop loop get_byte ; loop for getting N BYTEs mov SI, 007Eh ; insert 'terminator' in string array mov [DI], SI ; pop DI ; pop stored registers pop SI pop BP ret ; return input ENDP END
assign_3_c_part.c
#include
int main(void){
int n; //number of characters to input
extern void input(int, char*); //this is external asm function
int chk(char); // checking function taking one char at a time
printf("Enter number of characters to read, please keep this integer small \n");
scanf("%d", &n); //input number of characters to read
char string[n]; //array to store those characters
input(n, &string); //go to external function, ask it to read n (4) characters into array 'string'
// now the input stored in anArray
int c=0; //loop counter
(while c<4){ //go through an array and check every character
if (string[c]!='~') printf("%c", string[c]); else break;
c++;
}
}
int chk(char x){
int _ret=0;
if (x=='0' || x=='1' || x=='2' || x=='3' || x=='4' || x=='5' || x=='6' || x=='7' || x=='8' || x=='9' || x=='10' || x=='A' || x=='B' || x=='C' || x=='D' || x=='E' || x=='F')
printf("%c\n", x);
_ret=1;
break;
else
printf("NOT A DIGIT\n");
break;
return _ret;
}