以下链接解释了UNIX(BSD风格)和Linux的x86-32系统调用约定:
但是UNIX和Linux上的x86-64系统调用约定是什么?
64位Linux默认使用小内存模型,它将所有代码和静态数据置于2GB地址限制之下.这可确保您可以使用32位绝对地址.较旧版本的gcc使用静态数组的32位绝对地址,以便为相对地址计算保存额外的指令.但是,这不再有效.如果我尝试在汇编中创建一个32位的绝对地址,我会收到链接器错误:"在创建共享对象时,不能使用".data"重定位R_X86_64_32S;使用-fPIC重新编译".当然,此错误消息具有误导性,因为我没有创建共享对象,-fPIC也没有帮助.到目前为止我发现的是:gcc版本4.8.5对静态数组使用32位绝对地址,gcc版本6.3.0不使用.版本5可能也没有.binutils 2.24中的链接器允许32位绝对地址,而2.28则不允许.
这种变化的后果是必须重新编译旧库并破坏传统汇编代码.
现在我想问一下:这个改变是什么时候做的?它在某处记录了吗?是否有一个链接器选项,使其接受32位绝对地址?
所以我正在我的mac上学习x86_64 nasm程序集以获得乐趣.在hello world和一些基本的算术之后,我尝试从这个站点复制一个稍高级的hello world程序并将其修改为64位intel,但我无法摆脱这一个错误消息:hello.s:53: error: Mach-O 64-bit format does not support 32-bit absolute addresses.这是我用来汇编和链接的命令:nasm -f macho64 hello.s && ld -macosx_version_min 10.6 hello.o.这是相关的:
cmp rsi, name+8
Run Code Online (Sandbox Code Playgroud)
rsi是我在循环中用于索引的寄存器,name是为用户输入保留的四字,这是名称,到目前为止已经写入了.
这是代码的一部分(要查看其余部分,单击链接并转到底部,唯一的区别是我使用64位寄存器):
loopAgain:
mov al, [rsi] ; al is a 1 byte register
cmp al, 0x0a ; if al holds an ascii newline...
je exitLoop ; then jump to label exitLoop
; If al does not hold an ascii newline...
mov rax, 0x2000004 ; System call write = 4 …Run Code Online (Sandbox Code Playgroud) 我对Mac上的x64-assembly很新,所以我很困惑在64位中移植一些32位代码.
程序应该只通过printfC标准库中的函数打印出一条消息.
我已经开始使用这段代码:
section .data
msg db 'This is a test', 10, 0 ; something stupid here
section .text
global _main
extern _printf
_main:
push rbp
mov rbp, rsp
push msg
call _printf
mov rsp, rbp
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
用这种方式用nasm编译它:
$ nasm -f macho64 main.s
Run Code Online (Sandbox Code Playgroud)
返回以下错误:
main.s:12: error: Mach-O 64-bit format does not support 32-bit absolute addresses
Run Code Online (Sandbox Code Playgroud)
我试图修复问题字节,将代码更改为:
section .data
msg db 'This is a test', 10, 0 ; something stupid here
section .text
global _main
extern _printf …Run Code Online (Sandbox Code Playgroud) 当我使用时nasm -f macho64 asm1.asm,出现以下错误:
asm1.asm:14: 错误:Mach-O 64 位格式不支持 32 位绝对地址
这是 asm1.asm
SECTION .data ;initialized data
msg: db "Hello world, this is assembly", 10, 0
SECTION .text ;asm code
extern printf
global _main
_main:
push rbp
mov rbp, rsp
push msg
call printf
mov rsp, rbp
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
我对汇编真的很陌生,几乎不知道这些命令的作用。知道这里有什么问题吗?
我正在尝试将一些高性能的汇编函数编写为练习,并且遇到了在运行程序时发生的奇怪的段错误,但在valgrind或nemiver中却没有.
基本上一个不应该运行的cmov,带有一个越界的地址,即使条件总是假的,也会让我发生段错误
我有一个快速和慢速的版本.缓慢的一直在工作.快速的一个工作,除非它收到一个非ascii字符,此时它崩溃可怕,除非我在adb或nemiver上运行.
ascii_flags只是一个128字节的数组(最后有一点空间),包含所有ASCII字符(alpha,numeric,printable等)的标志
这工作:
ft_isprint:
xor EAX, EAX ; empty EAX
test EDI, ~127 ; check for non-ascii (>127) input
jnz .error
mov EAX, [rel ascii_flags + EDI] ; load ascii table if input fits
and EAX, 0b00001000 ; get specific bit
.error:
ret
Run Code Online (Sandbox Code Playgroud)
但这不是:
ft_isprint:
xor EAX, EAX ; empty EAX
test EDI, ~127 ; check for non-ascii (>127) input
cmovz EAX, [rel ascii_flags + EDI] ; load ascii table if input fits
and EAX, flag_print ; get …Run Code Online (Sandbox Code Playgroud) 我正在尝试学习如何编写汇编代码,我是在http://gnu.mirrors.pair.com/savannah/savannah//pgubook/ProgrammingGroundUp-0-8.pdf的帮助下完成的.这是一个很好的资源,我正在尝试以Macho64格式为我的Mac编写64位代码.
我遇到了绝对和相对寻址的麻烦.
这是我的代码:
DEFAULT REL
;PURPOSE: This program finds the maximum number of a set of data items
;
;VARIABLES: The registers have the following uses
;
; rbx - Holds the index of the data item being examined
; rdi - Largest data item found
; rax - Current data item
;
; The following memory locations are used:
;
; data_items - contains the item data. A 0 is used to terminate the data
;
global …Run Code Online (Sandbox Code Playgroud) 简而言之,当我db在我的.data部分中有多个部分时,编译的地址/标签在NASM编译时关闭.在我的测试中,它们在得到的Mach-O二进制文件中关闭了256个字节.
我使用的软件:
nasm NASM版本2.11.08,根据x84_64 ASM的要求通过Homebrew安装gobjdump GNU objdump(GNU Binutils)2.25.1,通过Homebrew安装clang Apple LLVM版本6.1.0(clang-602.0.53)(基于LLVM 3.6.0svn)以下面的"hello world"NASM程序集为例.
main.sglobal _main
section .text
_main:
mov rax, 0x2000004
mov rdi, 1
lea rsi, [rel msg]
mov rdx, len
syscall
mov rax, 0x2000001
mov rdi, 0
syscall
section .data
msg: db "Hello, world!", 10
len: equ $ - msg
Run Code Online (Sandbox Code Playgroud)
编译并运行:
/usr/local/bin/nasm -f macho64 -o main.o main.s
clang -o main main.o
./main
Run Code Online (Sandbox Code Playgroud)
这很好用,并产生以下输出:
Hello, world!
Run Code Online (Sandbox Code Playgroud)
现在,要添加另一条消息,我们只需要在数据部分添加另一个字符串,另一个syscall …
我有一个内存位置,其中包含一个我想要与另一个角色进行比较的角色(并且它不在堆栈的顶部,所以我不能只是pop它).如何引用内存位置的内容以便进行比较?
基本上我如何在语法上做到这一点.
我正在尝试使用NASM学习MacOS程序集,我无法使用一个简单的程序来工作.我正在尝试"Hello,World"的变体,其中两个单词由宏独立调用.我的源代码如下所示:
%macro printString 2
mov rax, 0x2000004 ; write
mov rdi, 1 ; stdout
mov rsi, %1
mov rdx, %2
syscall
%endmacro
global start
section .text
start:
printString str1,str1.len
printString str2,str2.len
mov rax, 0x2000001 ; exit
mov rdi, 0
syscall
section .data
str1: db "Hello,",10,
.len: equ $ - str1
str2: db "world",10
.len: equ $ - str2
Run Code Online (Sandbox Code Playgroud)
预期结果应该是:
$./hw
Hello,
World
$
Run Code Online (Sandbox Code Playgroud)
相反,我得到:
$./hw
Hello,
$
Run Code Online (Sandbox Code Playgroud)
我错过了什么?我如何解决它?
编辑:我正在使用以下命令编译和运行:
/usr/local/bin/nasm -f macho64 hw.asm
ld -macosx_version_min 10.7.0 -lSystem -o hw …Run Code Online (Sandbox Code Playgroud)