x86显示输出的其余部分(内联)
问题描述:
下面的代码假设有显示如果哪个数字更大或者它们是否相等和总和,但我得到的只是总和,如果我删除了总和部的第一部分,其中显示的数字是否等于x86显示输出的其余部分(内联)
section .rodata
prompt1 db "Enter an integer: ",0 ; 0 is null character
prompt2 db "Enter another integer: ",0
num_format db "%ld",0
format_str1 db "The greater of %ld and %ld is %ld.",10,0 ; 10 is LF
format_str2 db "The sum of %ld and %ld is %ld.",10,0 ; 10 is LF
equalprompt db "%ld and %ld are equal.",10,0 ; 10 is LF
section .text
global main ; main and _start are both valid entry points
extern printf, scanf ; these will be linked in from glibc i
main:
; prologue
push rbp ; save base pointer to the stack
mov rbp, rsp ; base pointer = stack pointer
sub rsp, 16 ; make room for two long integers on the stack
push rbx ; push callee saved registers onto the stack
push r12 ; push automatically decrements stack pointer
push r13
push r14
push r15
pushfq ; push register flags onto the stack
; prompt for first integer
mov rdi, dword prompt1 ; double word is 4 bytes; a word is 2 bytes
; rdi = 32-bit address of prompt1
xor rax, rax ; rax is return value register - zero it out
call printf ; call the C function from glibc
; read first integer
lea rsi, [rbp-8] ; load effective address - this instruction
; computes the address 8 bytes above the
; base pointer - the integer read by scanf
mov rdi, dword num_format ;
xor rax, rax ; zero out return value register
call scanf ; call C function
; scanf reads the input as an integer
; prompt for second integer
mov rdi, dword prompt2
xor rax, rax
call printf
; read second integer
lea rsi, [rbp-16]
mov rdi, dword num_format
xor rax, rax
call scanf
; determine if num2 (second integer) is greater than num1 (first integer)
xor rbx, rbx ; RBX = 0x0
mov rax, [rbp-16] ; RAX = num2 ; load rax with value at rdb-16
cmp rax, [rbp-8] ; compute (num1) - (num2) and set condition codes
; in machine status word register based on result
jl lessthan ; jump if num1 <= num2
je equal
; num1 > num2
mov rdi, dword format_str1
mov rsi, [rbp-8] ; num1
mov rdx, [rbp-16] ; num2
mov rcx, [rbp-16] ; greater of the two
;mov rcx, 0
; add rcx, rsi
; add rcx, rdx
; xor rax, rax
jmp sum
lessthan:
; num1 < num2
mov rdi, dword format_str1
mov rsi, [rbp-8] ; num1
mov rdx, [rbp-16] ; num2
mov rcx, [rbp-8] ; greater of the two
;mov rcx, 0
;add rcx, rsi
; add rcx, rdx
; xor rax, rax
jmp sum
equal:
mov rdi, dword equalprompt
mov rsi, [rbp-8] ; num1
mov rdx, [rbp-16] ; num2
jmp sum
sum:
mov rdi, dword num_format ;
mov rdi, dword format_str2
mov rsi, rsi ; num1
mov rdx, rdx ; num2
mov rcx, 0
add rcx, rsi
add rcx, rdx
jmp exit
exit:
call printf
; epilogue
popfq
pop r15
pop r14
pop r13
pop r12
pop rbx
add rsp, 16 ; set back the stack level
leave
ret
示例输出是这样的:
Enter an integer: 7
Enter another integer: 3
The sum of 7 and 3 is 10
答
mov rax, [rbp-16] ; RAX = num2 ; load rax with value at rdb-6 cmp rax, [rbp-8] ; compute (num1) - (num2) and set condition code jl lessthan ; jump if num1 <= num2 je equal
从这个cmp
开始的评论大多是错误的(反向)!
什么cmp
计算是RAX - [rbp-8]
,所以num2 - num1。
您的jl lessthan
跳转如果num2 < num1。 幸运的是,在后面的代码片段中填充两者中较大者的代码是正确的。
当代码到达标签总和,你立即摧毁你精心设置了RDI
寄存器开始。您应该首先发出call printf
以显示显示较大数字的第一行结果。此后,您可以设置显示总和的第二行结果。
为什么不简化代码呢?您可以从num1中的RSI
和num2中的RDX
开始,然后比较这些寄存器,而不是在RAX
中进行,后来不得不重复加载这些寄存器。
也不要害怕做一些看似无用的操作,如果这样做可以减少程序中分支的数量。看看下一代码如何加载RDI
,并可能以后需要重新加载其他值?加载RCX
也可能需要重新加载。
mov rsi, [rbp-8] ; num1
mov rdx, [rbp-16] ; num2
cmp rsi, rdx
mov rdi, dword equalprompt
je sum
mov rdi, dword format_str1
mov rcx, rsi ; num1 is greater of the two
jg sum ; jump if num1 > num2
mov rcx, rdx ; num2 is greater of the two
sum:
call printf
mov rcx, 0 add rcx, rsi
有一个在做这种方式没有任何意义。只需要mov
第一个号码变成RCX
使用mov rcx, rsi
。
mov rdi, dword format_str2
mov rcx, rsi
add rcx, rdx
call printf
请删除行号,以便其他用户可以组装您的代码并将其插入调试器。 – fuz
线路120上的'call printf'只能执行一个或另一个。我认为你应该在第109行添加另一个'call printf'。 –
你不需要在函数中保存FLAGS,它们像'rcx','rdx'等一样被调用。此外,你不需要推动/弹出你永远不会碰到的寄存器(比如'r12')。这只是一个浪费的指令,就像'jmp exit' /'exit:'一样。你不需要跳过空行;反正总是执行下一条指令。 –