我正在尝试在汇编中实现以下程序:
int number;
printf("\n%s","Enter an integer: ");
scanf("%d",&number);
number=7-number*3;
printf("\n%s%d\n\n","The integer is: ",number);
到目前为止,我的尝试是:
.386
.model flat, c
.stack 100h
printf PROTO arg1:Ptr Byte, printlist:VARARG
scanf PROTO arg2:Ptr Byte, printlist:VARARG
.data
in1fmt byte "%d",0
msg1fmt byte 0Ah,"%s",0
msg1 byte "Enter an integer: ",0
msg2fmt byte 0Ah,"%s%d",0Ah,0Ah,0
msg2 byte "The integer is: ",0
number sdword ?
.code
main proc
INVOKE printf, ADDR msg1fmt, ADDR msg1
INVOKE scanf, ADDR in1fmt, ADDR number
mov eax, number
mov ebx, 3
imul ebx
mov number, eax
mov eax, 7
sub eax, number
INVOKE printf, ADDR msg2fmt, ADDR msg2, eax
ret
main endp
end
第一个问题似乎是eax没有存储在数量中。当我将eax输入数字后打印出数字值时,输出值为21,输入为30. eax为90,但将eax移入数字后为21。
我确定我错过了一些简单的事情,但我无法看清楚我的错误。
答案 0 :(得分:0)
enterMsg db 'Enter an integer: ',0
resultMsg db 'The integer is: %d\r\n',0 ; yep, I refactored this one
stringPattern db '%s',0
; ...
proc main
push ebp
mov ebp,esp
sub esp,4
lea eax,[ds:enterMsg]
push eax
lea eax,[ds:stringPattern]
push eax
call printf ; printf("%s", enterMsg); // btw, why?
add esp,8
lea eax,[ebp - 4]
push eax
lea eax,[ds:intPattern]
push eax
call scanf ; scanf("%d", &number);
add esp,8
mov eax,[dword ptr ss:ebp - 4]
push eax
call calculate ; number = calculate(number);
add esp,4
mov [dword ptr ss:ebp - 4],eax
lea eax,[ebp - 4]
push eax
lea eax,[ds:resultMsg]
push eax
call printf ; printf(resultMsg, number);
add esp,8
mov esp,ebp
pop ebp
ret
endp main
; number=7-number*3;
proc calculate
push ebp
mov ebp,esp
push ebx
; not considering integer overflow for now
mov eax,[dword ptr ss:ebp + 8]
mov ebx,3
imul ebx
neg eax
add eax,7
pop ebx
mov esp,ebp
pop ebp
ret
endp calculate
C程序很容易转换为ASM。
使用 cdecl 调用约定,您可以从右向左推送子例程的参数,调用子例程,并在eax
中获取返回值(如果有的话;或者ST0用于浮点数)。然后你清理堆栈,就是这样。
我认为问题是你在堆栈上推送结果的值而不是指向它的指针。但不确定;我已经有一段时间没在ASM中使用C rtl了