scanf
을 사용하여 4 개의 부동을 입력하려고하면 스택에 저장하고 vmovupd
을 사용하여 레지스터에 복사합니다. 내 문제는 그 4 개의 숫자를 출력하려고 할 때입니다. 프로그램의 오류는 printf
입니다.printf의 분할 오류 - NASM 64 비트 Linux
나는 그것이 스택과 함께한다고 가정하지만, 여러 번 (한 번에 여러 명령어) 터지는 것을 시도해 보았다. 나는 여전히 어셈블리 코딩에 익숙하지 않기 때문에 gdb
을 사용하면 나에게 너무 진보적이다.
debug
이라는 파일이 포함되어 있습니다. 그것은 제가 레지스터와 스택을 볼 수있게합니다. (그 이유는 dumpstack
입니다.) 그건 교수님이 제공 한 것이지 만 도움이되지는 않았지만 분명히 충분하지 않았습니다.
#include <iostream>
using namespace std;
extern "C" double ComputeElectricity();
int main()
{
cout << "Welcome to electric circuit processing by Chris Tarazi." << endl;
double returnValue = ComputeElectricity();
cout << "The driver received this number: " << returnValue << endl;
return 0;
}
을 그리고 여기 ASM
코드입니다 :
다음은 .cpp
의
%include "debug.inc"
extern printf
extern scanf
global ComputeElectricity
;---------------------------------Declare variables-------------------------------------------
segment .data
greet db "This progam will help you analyze direct current circuits configured in parallel.", 10, 0
voltage db "Please enter the voltage of the entire circuit in volts: ", 0
first db "Enter the power consumption of device 1 (watts): ", 0
second db "Enter the power consumption of device 2 (watts): ", 0
third db "Enter the power consumption of device 3 (watts): ", 0
fourth db "Enter the power consumption of device 4 (watts): ", 0
thankyou db "Thank you. The computations have completed with the following results.", 10, 0
circuitV db "Curcuit total voltage: %1.18lf v", 10, 0
deviceNum db "Device number: 1 2 3 4", 10, 0
power db "Power (watts): %1.18lf %1.18lf %1.18lf %1.18lf", 10, 0
current db "Current (amps): %1.18lf %1.18lf %1.18lf %1.18lf", 10, 0
totalCurrent db "Total current in the circuit is %1.18lf amps.", 10, 0
totalPower db "Total power in the circuit is %1.18lf watts.", 10, 0
bye db "The analyzer program will now return total power to the driver.", 10, 0
string db "%s", 0
floatfmt db "%lf", 0
fourfloat db "%1.18lf %1.18lf %1.18lf %1.18lf", 0
;---------------------------------Begin segment of executable code------------------------------
segment .text
dumpstack 20, 10, 10
ComputeElectricity:
;dumpstack 30, 10, 10
;---------------------------------Output greet message------------------------------------------
mov qword rax, 0
mov rdi, string
mov rsi, greet
call printf
;---------------------------------Prompt for voltage--------------------------------------------
mov qword rax, 0
mov rdi, string
mov rsi, voltage
call printf
;---------------------------------Get voltage--------------------------------------------------
push qword 0
mov qword rax, 0
mov rdi, floatfmt
mov rsi, rsp
call scanf
vbroadcastsd ymm15, [rsp]
pop rax
;---------------------------------Prompt for watts 1--------------------------------------------
mov qword rax, 0
mov rdi, string
mov rsi, first
call printf
;---------------------------------Get watts 1---------------------------------------------------
push qword 0
mov qword rax, 0
mov rdi, floatfmt
mov rsi, rsp
call scanf
;---------------------------------Prompt for watts 2--------------------------------------------
mov qword rax, 0
mov rdi, string
mov rsi, second
call printf
;---------------------------------Get watts 2---------------------------------------------------
push qword 0
mov qword rax, 0
mov rdi, floatfmt
mov rsi, rsp
call scanf
;---------------------------------Prompt for watts 3--------------------------------------------
mov qword rax, 0
mov rdi, string
mov rsi, third
call printf
;---------------------------------Get watts 3---------------------------------------------------
push qword 0
mov qword rax, 0
mov rdi, floatfmt
mov rsi, rsp
call scanf
;---------------------------------Prompt for watts 4--------------------------------------------
mov qword rax, 0
mov rdi, string
mov rsi, fourth
call printf
;---------------------------------Get watts 4---------------------------------------------------
push qword 0
mov qword rax, 0
mov rdi, floatfmt
mov rsi, rsp
call scanf
;dumpstack 50, 10, 10
;---------------------------------Move data into correct registers------------------------------
vmovupd ymm14, [rsp] ; move all 4 numbers from the stack to ymm14
pop rax
pop rax
pop rax
pop rax
;dumpstack 55, 10, 10
vextractf128 xmm10, ymm14, 0 ; get lower half
vextractf128 xmm11, ymm14, 1 ; get upper half
;---------------------------------Move data into low xmm registers------------------------------
movsd xmm1, xmm11 ; move ymm[128-191] (3rd value) into xmm1
movhlps xmm0, xmm11 ; move from highest value from xmm11 to xmm0
movsd xmm3, xmm10
movhlps xmm2, xmm10
;showymmregisters 999
;---------------------------------Output results-------------------------------------------------
;dumpstack 60, 10, 10
mov rax, 4
mov rdi, fourfloat
push qword 0
call printf
pop rax
ret
단순히 'printf'를 호출하는 'C'프로그램을 작성하고 어셈블리 목록을 생성 한 다음 해당 목록에서 컴파일러가 어떻게 수행하는지 배우십시오. – PaulMcKenzie
@PaulMcKenzie 당신이 그것을보고 올바른 방향으로 나를 가리킬 수 있다면 [this] (http://goo.gl/WwIITD)를 생성했습니다. 나는 아직도 그것이 일어나고있는 이유를 알 수 없다. – ctzdev
사람들이 컴파일러가 생성 한 코드를 연구하는 것을 계속 주장하는 것을 당황스럽게 생각한다. 리버스 엔지니어링은 거의 가장 어려운 가장 복잡한 작업이며, 특히 컴파일러가 생성 한 코드에서 잘못된 결론을 신속하게 이끌어 낼 수 있습니다. 대신, 관련 문서 (ABI 및 명령어 세트)를 읽고 디버거를 사용하십시오. – Jester