问题描述
该程序的目的是从用户那里获取3个参数和一个附加参数,然后求和。
我让它起作用,以便它找到3个参数的总和并打印出总和。
如何打印不带参数的字符串,如何从用户那里获取输入并打印输入?
includelib legacy_stdio_deFinitions.lib
extrn printf:near,scanf:near
.data ; Data section
istr db 'Please enter an integer: '
stri byte '%lld',0AH,00
ostr byte 'The sum of proc. and user inputs (%lld,%lld,%lld): %lld',00
.code ; Code section
public use_scanf ; int use_scanf(long long a,long long b,long long c)
use_scanf: ; {
mov rax,0 ; sum = 0;
add rax,rcx ; sum += a;
add rax,rdx ; sum += b;
add rax,r8 ; sum += c;
; printf('Please enter an integer');
; scanf();
; printf('%lld',&inp_int);
mov r9,3 ; temp inp_int
add rax,r9 ; sum += inp_int;
push rbx ; save reg rbx to make space
mov rbx,rax ; save sum in rbx
push rax ; sum.push
push rax ; sum.push
push r9 ; usrinput.push
sub rsp,32 ; allocate shadow space
mov r9,r8 ; arg3 = c;
mov r8,rdx ; arg2 = b;
mov rdx,rcx ; arg1 = a
lea rcx,ostr ; arg0 = ostr;
call printf ; printf(ostr);
add rsp,56 ; clear shadow space and vars from stack
mov rax,rbx ; retVal = sum
pop rbx ; return rbx to prevIoUs value
ret ; return retVal}
编辑:控制台输出
Please enter an integer: 2
use_scanf_spill4 equ 12 * 8 ; The slots above return address that are
The sum of proc. and user inputs (1,2,3,1002523588520): 1002523588526
use_scanf(1,3) = 73 ERROR: should be 7018134685179969542
Please enter an integer: 2
The sum of proc. and user inputs (-3,-2,1002523588520): 1002523588517
use_scanf(-3,-2) = 75 ERROR: should be 7018134685179969533
Please enter an integer: 3
The sum of proc. and user inputs (4,-4,1002523588520): 1002523588523
use_scanf(4,-4) = 74 ERROR: should be 7018134685179969539
Please enter an integer: -3
The sum of proc. and user inputs (-3,-3,1002523588520): 1002523588510
use_scanf(-3,-4) = 76 ERROR: should be 7018134685179969526
以下是要对其进行测试的cpp文件。
void check(const char *s,_int64 v,_int64 expected) {
std::cout << s << " = " << v;
if (v == expected) {
std::cout << " OK";
}
else {
std::cout << " ERROR: should be " << expected;
}
std::cout << "\n";
}
_int64 sum_scanf;
_int64 sum_check;
sum_scanf = use_scanf(1,3);
sum_check = 1 + 2 + 3 + inp_int;
check("use_scanf(1,3)",sum_scanf,sum_check);
std::cout << "\n";
sum_scanf = use_scanf(-3,-2);
sum_check = -3 + 2 - 2 + inp_int;
check("use_scanf(-3,-2)",sum_check);
std::cout << "\n";
sum_scanf = use_scanf(4,-4);
sum_check = 4 + 3 - 4 + inp_int;
check("use_scanf(4,-4)",-4);
sum_check = -3 - 3 - 4 + inp_int;
check("use_scanf(-3,sum_check);
解决方法
您有通话约定问题。首先,堆栈深度必须除以8。第二,除了在序言和结语中,您不使用推入和弹出。
我猜您是从一个基本的C实现开始的,将其分解,然后开始编辑。编译器在这里引入了一些高级技巧,您最好在早期阶段避免这样做。因此,我们开始重写。
我没有尝试优化任何东西。
;Take your globals from above -- you will need
use_scanf_spill4 equ 12 * 8 ; The slots above return address that are
use_scanf_spill3 equ 11 * 8 ; for spilling arguments. In theory you can
use_scanf_spill2 equ 10 * 8 ; use them for something else but I didn't.
use_scanf_spill1 equ 9 * 8
use_scanf_space equ 7 * 8 ; it holds return addess -- don't clobber
use_scanf_sum equ 6 * 8
use_scanf_input equ 5 * 8
use_scanf_arg6 equ 5 * 8 ; same as use_scanf_input,but only 1 is used at a time
use_scanf_arg5 equ1 4 * 8
; 0,1,2,3 are argument zone
use_scanf:
; Allocate stack space
; this function doesn't use any non-call-clobbered registers
sub rsp,use_scanf_space
; spill input since we need it later
mov [rsp + use_scanf_spill1],rcx
mov [rsp + use_scanf_spill2],rdx
mov [rsp + use_scanf_spill3],r8
mov [rsp + use_scanf_spill4],r9
; Add arguments together and stash
add rcx,rdx
add rcx,r8
mov [rsp + use_scanf_sum],rcx
; print the promot
lea rcx,istr
call printf
; call scanf
lea rcx,[stri]
; Can't take the address of a register so we give it a memory slot
lea rdx,[rsp + use_scanf_input]
call scanf
; sum the values
mov rdx,[rsp + use_scanf_sum]
mov rax,[rsp + use_scanf_input]
add rax,rdx
; print out the arguments and total
; using rcx as scratch -- will clobber later
mov rdx,[rsp + use_scanf_spill1]
mov r8,[rsp + use_scanf_spill2]
mov r9,[rsp + use_scanf_spill3]
mov rcx,[rsp + use_scanf_input]
mov [rsp + use_scanf_arg5],rcx
mov [rsp + use_scanf_arg6],rax
lea rcx,[ostr]
call printf
; now leave
add rsp,use_scanf_space
ret