ฉันกำลังพยายามเรียนรู้ภาษาแอสเซมบลีจาก Linux Ubuntu 16.04 x64 ตอนนี้ฉันมีปัญหาดังต่อไปนี้: - สแกนจำนวนเต็ม n แล้วพิมพ์ตัวเลขตั้งแต่ 1 ถึง n
สำหรับ n = 5 ฉันควรมี 1 2 3 4 5 ฉันพยายามทำโดยใช้ scanf และ printf แต่หลังจากที่ฉันป้อนหมายเลข มันก็ออก
รหัสคือ:
;nasm -felf64 code.asm && gcc code.o && ./a.out
SECTION .data
message1: db "Enter the number: ",0
message1Len: equ $-message1
message2: db "The numbers are:", 0
formatin: db "%d",0
formatout: db "%d",10,0 ; newline, nul
integer: times 4 db 0 ; 32-bits integer = 4 bytes
SECTION .text
global main
extern scanf
extern printf
main:
mov eax, 4
mov ebx, 1
mov ecx, message1
mov edx, message1Len
int 80h
mov rdi, formatin
mov rsi, integer
mov al, 0
call scanf
int 80h
mov rax, integer
loop:
push rax
push formatout
call printf
add esp, 8
dec rax
jnz loop
mov rax,0
ret
ฉันรู้ว่าในลูปนี้ ฉันจะมีเอาต์พุตผกผัน (5 4 3 2 1 0) แต่ฉันไม่รู้ว่าจะตั้งเงื่อนไขอย่างไร
คำสั่งที่ฉันใช้มีดังต่อไปนี้:
nasm -felf64 code.asm && gcc code.o && ./a.out
คุณช่วยฉันค้นหาว่าฉันผิดพลาดตรงไหนได้ไหม?
push
อาร์กิวเมนต์สำหรับprintf
ในสแต็ก คุณใช้แหล่งข้อมูลใดในการดำเนินการเช่นนี้ (ฉันสงสัยว่าคุณกำลังเปลี่ยนโค้ด 32b/บทช่วยสอนเป็น 64b แต่นั่นจะไม่ได้ผลง่ายๆ มันซับซ้อนกว่า... ในตอนนี้ หากคุณมีทรัพยากร asm 32b ที่ดีสำหรับการเรียนรู้ การสอนจะง่ายกว่ามาก วิธีสร้างไบนารี 32b ภายใต้ 64b linux และทำงานกับสิ่งนั้นแทน) ... อย่างใดอย่างหนึ่ง หรือทรัพยากร 64b ของคุณมีคุณภาพต่ำ และลองใช้สิ่งที่ดีกว่านี้... - person Ped7g   schedule 20.11.2017printf
เป็นหนึ่งในวิธีที่ซับซ้อนกว่าในการทำให้ถูกต้อง เนื่องจากมีจำนวนอาร์กิวเมนต์ที่แปรผัน ดังนั้นคุณจำเป็นต้องรู้รูปแบบการเรียกที่เหมาะสมนอกเหนือจากพื้นฐาน คุณสามารถตรวจสอบบทช่วยสอนนี้ (ดูเหมือนว่าจะกำหนดเป้าหมายตรง nasm+libc+32b และดูเหมือนว่าจะได้รับการแสดงความคิดเห็นที่ดี): csee.umbc.edu/portal/help/nasm/sample.shtml และหากคุณเพิ่งเริ่มต้นด้วยการประกอบ ฉันจะข้ามการเรียกใช้ฟังก์ชัน libc ไปเลย และลองเล่นกับ x86 ล้วนๆ คำแนะนำ (ทำคณิตศาสตร์) ตรวจสอบค่าในดีบักเกอร์เท่านั้น - person Ped7g   schedule 20.11.2017printf
: stackoverflow.com/questions/47362660/ ... อย่าลังเลที่จะถามหากมีสิ่งใดไม่ชัดเจนหรือเหมาะกับคุณ (เกี่ยวกับบรรทัดคำสั่งที่ยาว ... ดูอาจจะน่าเบื่อ แต่ฉันใช้โปรแกรมแก้ไขข้อความ Kate พร้อมการตั้งค่าวิธี build ดังนั้นฉันจึงไม่สนใจชื่อที่ยาวเหล่านั้น ... จากนั้นอีกครั้งคุณสามารถจัดเก็บคำสั่งเหล่านั้นในเชลล์สคริปต์ได้ หรือแม้แต่สร้างไฟล์) น่าเศร้าที่ฉันไม่ได้สนใจที่จะเพิ่มตัวแปร 64b - person Ped7g   schedule 20.11.2017printf
จากแอสเซมบลี .. ขออภัย :D.. ยังมีอยู่ มีบทเรียนมากมายบนอินเทอร์เน็ต และฉันเหนื่อยเกินกว่าจะเขียนคำตอบทั้งหมดที่นี่ - person Ped7g   schedule 20.11.2017int 0x80
ในโหมด 64 บิต (stackoverflow.com /คำถาม/46087730/) จริงๆ แล้วปัญหาไม่ได้อยู่ที่การตัดสินใจว่าจะใช้การเรียกของระบบหรือฟังก์ชั่นไลบรารี stdio และแย่กว่านั้นคือการใช้call scanf
/int 80h
ดังนั้นหมายเลข syscall จึงถูกกำหนดโดยค่าส่งคืน scanf!!!! - person Peter Cordes   schedule 20.11.2017