我收到了这个错误:
loop AdderLoop
错误A2075:跳转目标太远:按25个字节
这是一个加法器程序。
我还在学习pop
和push
所以也许我做的不对,但似乎我的变量ARRAY_SIZE没有正确存储?
我在程序开始处按下存储ARRAY_SIZE的寄存器,并在程序结束时将其弹出。
.386 ;identifies minimum CPU for this program
.MODEL flat,stdcall ;flat - protected mode program
;stdcall - enables calling of MS_windows programs
;allocate memory for stack
;(default stack size for 32 bit implementation is 1MB without .STACK directive
; - default works for most situations)
.STACK 4096 ;allocate 4096 bytes (1000h) for stack
;*******************MACROS********************************
;mPrtStr
;usage: mPrtStr nameOfString
;ie to display a 0 terminated string named message say:
;mPrtStr message
;Macro definition of mPrtStr. Wherever mPrtStr appears in the code
;it will be replaced with
mPrtStr MACRO arg1 ;arg1 is replaced by the name of string to be displayed
push edx
mov edx, offset arg1 ;address of str to display should be in dx
call WriteString ;display 0 terminated string
pop edx
ENDM
;*************************PROTOTYPES*****************************
ExitProcess PROTO,
dwExitCode:DWORD ;from Win32 api not Irvine to exit to dos with exit code
ReadChar PROTO ;Irvine code for getting a single char from keyboard
;Character is stored in the al register.
;Can be used to pause program execution until key is hit.
WriteDec PROTO ;Irvine code to write number stored in eax
;to console in decimal
WriteString PROTO ;Irvine code to write null-terminated string to output
;EDX points to string
WriteChar PROTO ;write the character in al to the console
;************************ Constants ***************************
LF equ 0Ah ; ASCII Line Feed
;************************DATA SEGMENT***************************
.data
carryIn byte 0,0,0,0,1,1,1,1
inputA byte 0,0,1,1,0,0,1,1
inputB byte 0,1,0,1,0,1,0,1
ARRAY_SIZE equ $ - inputB
;The '$' acts as a place maker where you are currently in memory
;which at the end of the carryInNum array.
;The ending address of the carryInNum array minus the beginning
;address equals the total bytes of the carryInNum array
;which is stored in the ARRAY_SIZE constant.
;NOTE: there can be no other variables between the
;declation of the ARRAY_SIZE constant and the declaration
;of the array you are trying to calculate the size of.
;You can add LFs to the strings below for proper output line spacing
;but do not change anything between the quotes "do not change".
;I will be using a comparison program to compare your output to mine and
;the spacing must match exactly.
endingMsg byte "Hit any key to exit!",0
;Change my name to your name
titleMsg byte "Program 4 by ",LF,0
testingAdderMsg byte " Testing Adder",0
inputA_Msg byte " Input A: ",0
inputB_Msg byte " Input B: ",0
carryin_Msg byte " Carry in: ",0
sum byte " Sum: ",0
carryout byte " Carry Out: ",0
dashes byte LF," ------------",LF,0
;************************CODE SEGMENT****************************
.code
main PROC
mov ecx, ARRAY_SIZE ;ecx = ARRAY_SIZE
mov esi, 0 ;esi = 0
mPrtStr titleMsg ;print "Program 4 by"
AdderLoop:
mPrtStr inputA_Msg ;print " Input A: "
movzx eax, inputA[esi] ;eax = inputA[esi]
INVOKE WriteDec ;write decimal stored in eax
mov al, LF ;al = ASCII Line Feed
INVOKE WriteChar ;write the character stored in al
mPrtStr inputB_Msg ;print " Input B: "
movzx eax, inputB[esi] ;eax = inputB[esi]
INVOKE WriteDec ;write decimal stored in eax
mov al, LF ;al = ASCII Line Feed
INVOKE WriteChar ;write the character stored in al
mPrtStr carryin_Msg ;print " Carry in: "
movzx eax, carryIn[esi] ;eax = carryIn[esi]
INVOKE WriteDec ;write decimal stored in eax
mov al, LF ;al = ASCII Line Feed
INVOKE WriteChar ;write the character stored in al
call adder ;call the adder procedure
mPrtStr dashes ;print " ------------"
mPrtStr sum ;print " Sum: "
mov al, LF ;al = ASCII Line Feed
INVOKE WriteChar ;write the character stored in al
mPrtStr carryout ;print " Carry Out: "
mov al, LF ;al = ASCII Line Feed
INVOKE WriteChar ;write the character stored in al
add esi, 4 ;add 4 to esi to go to next element in the arrays
loop AdderLoop ;ARRAY_SIZE--, if ARRAY_SIZE = 0 then end, else loop
mPrtStr endingMsg ;print "Hit any key to exit!"
call ReadChar ;Pause program execution while user inputs a non-displayed char
INVOKE ExitProcess,0 ;Exit to dos: like C++ exit(0)
main ENDP
;IMPORTANT: Do not delete the function comment block below.
; Every function should have a similar comment block
; specifying what the function is about including:
; - Description
; - Input (Entry)
; - Output (Exit)
; - Registers used (REGS)
;************** Adder – Simulate a full Adder circuit
; Adder will simulate a full Adder circuit that will add together
; 3 input bits and output a sum bit and a carry bit
;
; Each input and output represents one bit.
;
; Note: do not access the arrays in main directly in the Adder function.
; The data must be passed into this function via the required registers below.
;
; ENTRY - EAX = input bit A
; EBX = input bit B
; ECX = Cin (carry in bit)
; EXIT - EAX = sum bit
; ECX = carry out bit
; REGS - EAX, EBX, ECX, ESI
;
; For the inputs in the input columns you should get the
; outputs in the output columns below:
;
; input output
; eax ebx ecx = eax ecx
; A + B + Cin = Sum Cout
; 0 + 0 + 0 = 0 0
; 0 + 1 + 0 = 1 0
; 1 + 0 + 0 = 1 0
; 1 + 1 + 0 = 0 1
; 0 + 0 + 1 = 1 0
; 0 + 1 + 1 = 0 1
; 1 + 0 + 1 = 0 1
; 1 + 1 + 1 = 1 1
;
; Note: the Adder function does not do any output.
; All the output is done in the main function.
;
;Do not change the name of the Adder function.
;
;See additional specifications for the Adder function on the
;class web site.
;
;You should use AND, OR and XOR to simulate the full adder circuit.
;
;You should save any registers whose values change in this function
;using push and restore them with pop.
;
;The saving of the registers should
;be done at the top of the function and the restoring should be done at
;the bottom of the function.
;
;Note: do not save any registers that return a value (ecx and eax).
;
;Each line of the Adder function must be commented and you must use the
;usual indentation and formating like in the main function.
;
;Don't forget the "ret" instruction at the end of the function
;
;Do not delete this comment block. Every function should have
;a comment block before it describing the function. FA17
Adder proc
push ecx ;store ARRAY_SIZE for later
movzx eax, inputA[esi] ;eax = inputA[esi]
movzx ebx, inputB[esi] ;ebx = inputB[esi]
movzx ecx, carryIn[esi] ;ecx = carryIn[esi]
push eax ;store inputA[esi] for later
xor eax, ebx ;eax = inputA[esi] XOR inputB[esi]
push eax ;store inputA[esi] XOR inputB[esi] for later
xor eax, ecx ;eax = (inputA[esi] XOR inputB[esi]) XOR carryIn[esi] (this is the sum)
pop eax ;pop inputA[esi] XOR inputB[esi] into eax
and ecx, eax ;eax = (inputA[esi] XOR inputB[esi]) AND carryIn[esi]
pop eax ;pop inputA[esi] into eax
and eax, ebx ;eax = inputA[esi] AND inputB[esi]
or ecx, eax ;ecx = ((inputA[esi] XOR inputB[esi]) AND carryIn[esi]) OR (inputA[esi] AND inputB[esi]) (this is the carry out)
pop ecx ;pop ARRAY_SIZE into ecx
ret ;return
Adder endp
END main
答案 0 :(得分:5)
问题是loop
只能向任一方向跳转最多128个字节。您的标签似乎离loop adderLoop
无法触及。考虑将loop
替换为dec ecx
,然后替换为jnz adderLoop
。有jnz
的变体可以跳得更远,解决了这个问题。通常,我建议避免使用loop
指令,因为它比可以替换它的dec ecx / jnz
对慢。