1。)写一个程序输出你的名字10次,每次向下对角方向移动,左边写。使用循环。
鲍勃
(空格)鲍勃
(空格)(空间)鲍勃
我尝试通过在每次添加更多空格打印字符串之前添加空格来解决这个问题。
2。)输入5个数字,一个数组中的一个数字。打印输入的最高值和输入的值。
这个我实际上做得很好,我只是想知道如何在输入时显示。
再次感谢您提供的任何帮助。我试着环顾四周,找不到符合这些要求的ASM问题。
编辑:使用x86处理器和MASM。我们的课本如下,http://kipirvine.com/asm/gettingStartedVS2012/index.htm#tutorial32。
答案 0 :(得分:0)
我得到了两个测试题的答案。
接下来是您的程序#1的代码,算法如下:
scounter = 1;
for ( ncounter = 10; ncounter > 0; ncounter-- )
{ for ( cx = scounter; cx > 0; cx-- )
printf( ' ' );
scounter++; // ANOTHER BLANK SPACE. STRING WILL MOVE TO THE RIGHT.
printf( 'Bob Wrath' );
printf( '\n' );
}
这很简单:两个计数器,一个用于名称,另一个用于空格。名称计数器是反向计数器(减少),空格计数器是正常的(增加)。现在汇编中的算法是用EMU8086制作的,但它与MASM的代码几乎相同(只需改变' $' by 0和DB by BYTE)。我使用注释作为小块代码的标题,使它们易于理解:
.stack 100h
.data
myname DB 'Bob Wrath$'
space DB ' $' ;BLANK SPACE.
break DB 13,10,'$' ;LINE BREAK.
ncounter DW ? ;COUNTER FOR NAMES.
scounter DW ? ;COUNTER FOR SPACES.
.code
;INITIALIZE DATA SEGMENT.
mov ax, @data
mov ds, ax
;INITIALIZE COUNTERS.
mov ncounter, 10 ;DISPLAY 10 NAMES.
mov scounter, 1 ;START WITH 1 SPACE TO THE LEFT.
names:
;DISPLAY SPACES BEFORE THE STRING.
mov cx, scounter ;NUMBER OF SPACES TO DISPLAY.
spaces:
mov dx, offset space
call printf
loop spaces ;CX-1. IF CX > 0 JUMP TO SPACES.
;INCREASE SPACES-COUNTER FOR THE NEXT ROUND.
inc scounter
;DISPLAY NAME.
mov dx, offset myname
call printf
;DISPLAY LINE BREAK.
mov dx, offset break
call printf ;DISPLAY LINE BREAK.
;CHECK IF NAMES-COUNTER IS 0.
dec ncounter ;NCOUNTER - 1.
jnz names ;IF (NCOUNTER != 0) JUMP TO NAMES.
;FINISH PROGRAM.
mov ax, 4c00h
int 21h
;-----------------------------------------
;PARAMETER : DX POINTING TO '$' FINISHED STRING.
proc printf
mov ah, 9
int 21h
ret
endp
现在节目#2。我再次使用EMU8086,这就是为什么我使用MASM可能不需要的一些程序(string2number,dollars,number2string)。该算法非常简单:从键盘中捕获5个(或任意多个)数字,将每个捕获的数字与最高值进行比较(非常重要:第一个最高值为0,这是必要的要找到最高,找到最低的第一个值应该是一个非常高的数字,比如32767,得到它?这样,第一个输入的数字会更高),最后,它显示的数字最高。请注意,我没有使用数组,因为它是不必要的,所解释的算法让我们在没有数组帮助的情况下找到最高数字:
.stack 100h
.data
counter dw ?
msj1 db 'Enter a number: $'
msj2 db 'The highest number is: $'
break db 13,10,'$'
str db 6 ;MAX NUMBER OF CHARACTERS ALLOWED (5).
db ? ;NUMBER OF CHARACTERS ENTERED BY USER.
db 6 dup (?) ;CHARACTERS ENTERED BY USER.
highest dw 0
buffer db 6 dup(?)
.code
;INITIALIZE DATA SEGMENT.
mov ax, @data
mov ds, ax
;-----------------------------------------
;CAPTURE 5 NUMBERS AND DETERMINE THE HIGHEST.
mov counter, 5 ;HOW MANY NUMBERS TO CAPTURE.
enter_numbers:
;DISPLAY MESSAGE.
mov dx, offset msj1
call printf
;CAPTURE NUMBER AS STRING.
mov dx, offset str
call scanf
;DISPLAY LINE BREAK.
mov dx, offset break
call printf
;CONVERT CAPTURED NUMBER FROM STRING TO NUMERIC.
mov si, offset str ;PARAMETER (STRING TO CONVERT).
call string2number ;NUMBER RETURNS IN BX.
;CHECK IF CAPTURED NUMBER IS THE HIGHEST.
cmp highest, bx
jae ignore ;IF (HIGHEST >= BX) IGNORE NUMBER.
;IF NO JUMP TO "IGNORE", CURRENT NUMBER IS HIGHER THAN "HIGHEST".
mov highest, bx ;CURRENT NUMBER IS THE HIGHEST.
ignore:
;CHECK IF WE HAVE CAPTURED 5 NUMBERS ALREADY.
dec counter
jnz enter_numbers
;-----------------------------------------
;DISPLAY HIGHEST NUMBER.
;FIRST, FILL BUFFER WITH '$' (NECESSARY TO DISPLAY).
mov si, offset buffer
call dollars
;SECOND, CONVERT HIGHEST NUMBER TO STRING.
mov ax, highest
mov si, offset buffer
call number2string
;THIRD, DISPLAY STRING.
mov dx, offset msj2
call printf
mov dx, offset buffer
call printf
;FINISH PROGRAM.
mov ax, 4c00h
int 21h
;-----------------------------------------
;PARAMETER : DX POINTING TO '$' FINISHED STRING.
proc printf
mov ah, 9
int 21h
ret
endp
;-----------------------------------------
;PARAMETER : DX POINTING TO BUFFER TO STORE STRING.
proc scanf
mov ah, 0Ah
int 21h
ret
endp
;------------------------------------------
;CONVERT STRING TO NUMBER.
;PARAMETER : SI POINTING TO CAPTURED STRING.
;RETURN : NUMBER IN BX.
proc string2number
;MAKE SI TO POINT TO THE LEAST SIGNIFICANT DIGIT.
inc si ;POINTS TO THE NUMBER OF CHARACTERS ENTERED.
mov cl, [ si ] ;NUMBER OF CHARACTERS ENTERED.
mov ch, 0 ;CLEAR CH, NOW CX==CL.
add si, cx ;NOW SI POINTS TO LEAST SIGNIFICANT DIGIT.
;CONVERT STRING.
mov bx, 0
mov bp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat:
;CONVERT CHARACTER.
mov al, [ si ] ;CHARACTER TO PROCESS.
sub al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
mov ah, 0 ;CLEAR AH, NOW AX==AL.
mul bp ;AX*BP = DX:AX.
add bx, ax ;ADD RESULT TO BX.
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
mov ax, bp
mov bp, 10
mul bp ;AX*10 = DX:AX.
mov bp, ax ;NEW MULTIPLE OF 10.
;CHECK IF WE HAVE FINISHED.
dec si ;NEXT DIGIT TO PROCESS.
loop repeat ;COUNTER CX-1, IF NOT ZERO, REPEAT.
ret
endp
;------------------------------------------
;FILLS VARIABLE WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THE STRING WILL BE DISPLAYED.
;PARAMETER : SI = POINTING TO STRING TO FILL.
proc dollars
mov cx, 6
six_dollars:
mov bl, '$'
mov [ si ], bl
inc si
loop six_dollars
ret
endp
;------------------------------------------
;CONVERT A NUMBER IN STRING.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (STR).
;PARAMETERS : AX = NUMBER TO CONVERT.
; SI = POINTING WHERE TO STORE STRING.
proc number2string
mov bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:
mov dx, 0 ;NECESSARY TO DIVIDE BY BX.
div bx ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER.
push dx ;PRESERVE DIGIT EXTRACTED FOR LATER.
inc cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
cmp ax, 0 ;IF NUMBER IS
jne cycle1 ;NOT ZERO, LOOP.
;NOW RETRIEVE PUSHED DIGITS.
cycle2:
pop dx
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ si ], dl
inc si
loop cycle2
ret
endp
希望这可以帮助您进行下一次测试。