So one of the problems that were in the exam for me is to make this group of code more efficient with at least 1 line less command. And I didn't know how to do it.The goal of this code is to get the 4 right bits of the first number,the left bits from the second number from the array (which its address is located in si) and then to merge those 8 bits- and to put the result in a 8 bit register. 0dh is the ASCII of enter,I need to make sure that enter isn't one of the chars that user had input,if it does 0 should replace it.(The array is an array of characters) This is the code:
I thought maybe she just meant to get the line that doesn't effect the returned value to outside of the function but she told me that that's not what she meant so its wrong.
cmp [byte ptr si],0Dh
je LessThan4
mov al,[si]
shl al,4;(a)-first nibble
inc si
cmp [byte ptr si],0Dh
je LessThan4
mov dl,[si]
and dl,240;11110000b
shr dl,4;(b)-second nibble
or al,dl;al=ab merging the nibbles
inc si
jmp Normal
LessThan4:
mov[byte ptr si],0
Normal:
ret
The excepted result is using 1 command,that will swap 2 commands in the current code. Edit: Honestly I don't know why did I use this line: mov[byte ptr si],0 I don't need it,I need to put 0 instead of enter if there is enter. But this is happening alone because the function ends if there is an enter in the array,and 0 is what replacing the second nibble or both of the nibbles but I did need to make sure al is 0. If this is what she meant im so embarrassed and tilted because I might not be able to get to the subject I want to learn next year in our class.): ): ): ): ): I should have been able to see it pretty easily so that's really bad for me...
Try this then:
lodsw ; load ax from [si], then increment si twice
cmp al, 0dh ; was the first character a CR?
jz enter1 ; if yes, abort
cmp ah, 0dh ; was the second character a CR?
jz enter2 ; if yes, abort
rol ax, 4 ; combine the digits in al and ah into al
ret
enter1: dec si ; return back to the first character
enter2: dec si ; return back to the second character
mov [byte ptr si], 0 ; terminate input with a NUL
ret
This implementation uses 11 instructions instead of the 15 instruction of your implementation, saving 4 instructions.
The expected result is using 1 command, that will swap 2 commands in the current code.
The and dl, 11110000b
instruction before the shr dl, 4
instruction is redundant. The shift right will by itself throw out the low 4 bits.
How the nibbles are combined
get the 4 right bits of the first number, the 4 left bits of the second number and then merge those 8 bits
The logical way to present this combination of bits would be to keep those 4 right bits aka low nibble in the low nibble of the result, and to keep those 4 left bits aka high nibble in the high nibble of the result. Your code doesn't do it that way and neither do the other answers. Perhaps because they want to mimic what you've written.
If the 1st number is in AL
and the 2nd number is in AH
then and ax, 0F00Fh
will mask away the unwanted bits and or al, ah
will leave the combination in AL
How 13 is replaced by 0
0Dh is the ASCII of enter. I need to make sure that enter isn't one of the chars that user had input. If it does 0 should replace it.
I think that you could be misinterpreting this "...0 should replace it."
Probably this is DOS and input was terminated with enter , and so a carriage return (13) was appended to the inputted characters. What your teachers warns about is that the value 13 cannot become part of the result. You replace it with zero in the calculation but not in memory .
Returning a result in AL
and keeping SI
put.
mov ax, [si]
cmp al, 13
jne L1
xor ax, ax ; Falling through shaves off an instruction
L1:
cmp ah, 13
jne L2
xor ah, ah
L2:
and ax, 0F00Fh
or al, ah
ret
Always returning a result in AL
and having SI
point at either the remaining characters or the terminating carriage return.
Again:
mov ax, [si]
cmp al, 13 ; If 1st byte is 13, then next byte is just garbage!
je CR1 ; ... so no further interpretation needed
and al, 0Fh
inc si
cmp ah, 13 ; If 2nd byte is 13, then result is based on 1st byte
je CR2 ; ... and that kind-of zero-replacement
and ah, 0F0h
inc si
or al, ah
...
jmp Again
CR1:
xor al, al
CR2:
...
The goal of this code is to get the 4 right bits of the first number,the left bits from the second number from the array (which its address is located in si) and then to merge those 8 bits- and to put the result in a 8 bit register. 0dh is the ASCII of enter,I need to make sure that enter isn't one of the chars that user had input,if it does 0 should replace it.
The task doesn't say exactly what the combo should look like, so just bringing them together in any register should suffice.
mov ax, [si]
loads AL
with the 1st number and AH
with the 2nd number.
The 4 right bits of the 1st number are in the low nibble (bits 3 to 0).
The 4 left bits of the 2nd number are in the high nibble (bits 7 to 4).
ROR ax, 4
will rotate the low nibble of AX
into bits 15-12, and shift the high nibble of AX
down into bits 11-8. Now AH
holds the combination of bits.
mov ax, [si]
cmp al, 13
je CR
cmp ah, 13
je CR
ror ax, 4 ; combine the digits in al and ah into al
ret
CR:
mov byte [si], 0
ret
This has but 9 instructions.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.