我正在阅读这个汇编教程并且我得到了这个例子,所以我决定尝试改进它。一旦我这样做了,它就停止工作了,所以我尝试将它转换为 AT&T 语法,这样我就可以用 gcc 编译它并获取调试信息(因为我在 OS X 上,而 nasm 不会为 Mach 生成调试信息- O 格式)。
我试图转换可以工作的原始程序,但在我使用 AT&T 语法编写后它停止工作。我使用 gdb 调试它,发现%rsp
我希望包含 argc 的 包含 value 0x93b2e5ad
。intel 语法版本没有发生这种情况。
所以我的问题是,为什么%rsp
在 AT&T 版本中 argc 的值不正确,而在 Intel 版本中却没有?
这是原始的 Intel 语法版本(我在教程中稍微修改了版本):
section .data
WRONG_ARGC db "Must be two command line argument", 0xa
WRONG_ARGC_SIZE equ 34
section .text
global start
start:
pop rcx
cmp rcx, 3
jne argcError
add rsp, 8
pop rsi
call str_to_int
mov r10, rax
pop rsi
call str_to_int
mov r11, rax
add r10, r11
mov rax, r10
xor r12, r12
jmp int_to_str
argcError:
mov rax, 0x2000004
mov rdi, 1
mov rsi, WRONG_ARGC
mov rdx, WRONG_ARGC_SIZE
syscall
jmp exit
; set rdi to exit status before calling
exit:
mov rax, 0x2000001
syscall
str_to_int:
xor rax, rax
mov rcx, 10
next:
cmp [rsi], byte 0
je return_str
mov bl, [rsi]
sub bl, 48
mul rcx
add rax, rbx
inc rsi
jmp next
return_str:
ret
int_to_str:
mov rdx, 0
mov rbx, 10
div rbx
add rdx, 48
; push rdx
dec rsp
mov rsp, rdx
inc r12
cmp rax, 0
jne int_to_str
jmp print
print:
; mov rax, 1
; mul r12
mov rax, r12
; mov r12, 8
; mul r12
mov rdx, rax
mov rax, 0x2000004
mov rdi, 1
mov rsi, rsp
syscall
mov rdi, 0
jmp exit
这是我将其转换为 AT&T 语法后的代码:
.data
WRONG_ARGC: .ascii "Must be two command line argument\n"
WRONG_ARGC_SIZE: .quad 34
.text
.globl _main
_main:
popq %rcx
cmpq $3, %rcx
jne argcError
addq $8, %rsp
popq %rsi
call str_to_int
movq %rax, %r10
popq %rsi
call str_to_int
movq %rax, %r11
addq %r11, %r10
movq %r10, %rax
xorq %r12, %r12
jmp int_to_str
argcError:
movq $0x2000004, %rax
movq $1, %rdi
movq WRONG_ARGC@GOTPCREL(%rsi), %rsi
movq WRONG_ARGC_SIZE@GOTPCREL(%rsi), %rdx
syscall
jmp exit
# set rdi to exit status before calling
exit:
movq $0x2000001, %rax
syscall
str_to_int:
xorq %rax, %rax
movq $10, %rcx
next:
cmpq $0, (%rsi)
je return_str
movb (%rsi), %bl
subb $48, %bl
mulq %rcx
addq %rbx, %rax
incq %rsi
jmp next
return_str:
ret
int_to_str:
movq $0, %rdx
movq $10, %rbx
divq %rbx
addq $48, %rdx
push %rdx
#decq %rsp
#movq %rdx, %rsp
incq %r12
cmpq $0, %rax
jne int_to_str
jmp print
print:
movq $1, %rax
mulq %r12
movq %r12, %rax
movq $8, %r12
mulq %r12
movq %rax, %rdx
movq $0x2000004, %rax
movq $1, %rdi
movq %rsp, %rsi
syscall
movq $0, %rdi
jmp exit
我像这样编译了英特尔版本:
nasm -f macho64 -o add_intel.o add_intel.s
ld -o add_intel add_intel.s
我编译了这样的 AT&T 版本:
gcc -o add_att add_att.s -g