- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
所以我写了一个基于NASM的程序,接收用户输入(准确的说是两个数),然后实现两个数的加减,然后打印回来。该程序在 NASM 中运行良好,但我在使用 GAS 时遇到了问题。由于段错误,使用 repne scasb
指令计算字符串长度的子例程让我很头疼。
我已经检查了代码中是否存在段错误,我已将错误定位在 repne scasb
行。
我基本上做的是将我制作的 NASM 代码翻译成相应的 GAS 代码。但是,正如我之前所说,它给了我一个段错误。在我从用户那里得到第一个号码后,更具体地说。
.section .data
msg: .ascii "Insert a number: "
msgLen = .-msg
msg2: .ascii "Insert another number: "
msg2Len = .-msg2
errorMsg: .ascii "Error: invalid character!\n"
errorMsgLen = .-errorMsg
displaySuma: .ascii "The result of the addition is: "
displaySumaLen = .-displaySuma
displayResta: .ascii "The result of the difference is: "
displayRestaLen = .-displayResta
enterChar: .ascii "\n"
terminator: .byte 0
.section .bss
.lcomm num1, 8
.lcomm num2, 8
.lcomm buffer, 10
.lcomm buffer2, 10
.section .text
.global _start
_start:
call _clear #clear registers. Probably an useless routine
call _msg1 #Display msg1
call _num1 #Read num1
movl num1, %edi
call _lenString #ECX now has num1 length
lea (num1), %esi
call _stringToInt #EAX now has num1 in integer
movl %eax, %r15d #R15D now has the integer
call _msg2 #Display msg2
call _num2 #Read num2
xor %edi, %edi #Clear EDI
movl num2, %edi #Moving num2 to EDI register to call _lenstring
xor %ecx, %ecx #Clear ECX
call _lenString #ECX has num2 length
xor %esi, %esi #clear ESI
lea (num2), %esi
call _stringToInt #EAX now has integer value of num2
mov %eax,%r14d ###R14D has num2 now
#Addition
#r8d = num1 + num2
mov %r15d, %r8d
add %r14d, %r8d #R8D has num1 + num2
#Difference
#If num1 > num2 =======> r9d = num1 - num2
#If num1 < num2 =======> r9d = num2 - num1
cmp %r14d, %r15d
jg .greater
mov %r14d, %r9d
sub %r15d, %r9d #R9D has num1 - num2
jmp .next
.greater:
mov %r15d, %r9d
sub %r14d, %r9d #R9D has num2 - num1
jmp .next
.next:
mov %r8d, %eax #Sum is now at EAX to convert it to ascii characters
lea (buffer), %esi
call _intToString
#EAX ascii of the sum
mov %eax, %r10d #Using R10D to store the new string
mov %r9d, %eax #Difference result is now at EAX
lea (buffer2), %esi
call _intToString
#EAX has the pointer to the difference result.
mov %eax, %r11d #Storing string in R10D
xor %edi, %edi
xor %r15d, %r15d
xor %r14d, %r14d
mov %r10d, %edi
call _lenString #ECX length of sum string
mov %ecx, %r15d #R15D now has that value
call _suma #This prints the sum result
xor %edi, %edi #Clear EDI
mov %r11d, %edi
call _lenString #ECX has length of dif. string
mov %ecx, %r14d #R14D has that value
call _resta #Print dif. result
movl $1, %eax #End of the program
movl $0, %ebx
int $0x80
_stringToInt:
xor %ebx, %ebx
.next_digit:
movzxb (%esi), %eax
cmp $0x30, %eax #These 4 lines check for invalid characters
jb _errorMsg
cmp $0x39, %eax
ja _errorMsg
inc %esi
sub $0x30, %eax ###Sub 48 (converts to integer)
imul $10, %ebx
add %eax, %ebx #ebx = ebx*10 + eax
loop .next_digit #loop [ECX] times
mov %ebx, %eax
ret
_intToString:
add $10, %esi
mov (terminator),%esi
mov $10, %ebx
.next_digit1:
xor %edx, %edx
div %ebx
add $0x30, %edx ##
dec %esi
mov %dl, (%esi)
test %eax, %eax
jnz .next_digit1
mov %esi, %eax
ret
#######################################################################################################
_msg1:
movl $4, %eax #msg1 routine
movl $1, %ebx
movl $msg, %ecx
movl $msgLen, %edx
int $0x80
ret
_num1:
movl $3, %eax #Reads first number
movl $0, %ebx
movl $num1, %ecx
movl $8, %edx
int $0x80
ret
_msg2:
movl $4, %eax #msg2 display
movl $1, %ebx
movl $msg2, %ecx
movl $msg2Len, %edx
int $0x80
ret
_num2:
movl $3, %eax #Reads the next number
movl $0, %ebx
movl $num2, %ecx
movl $8, %edx
int $0x80
ret
_salir:
movl $1, %eax #Exit
movl $0, %ebx
int $0x80
_errorMsg:
movl $4, %eax #Error msg
movl $1, %ebx
movl $errorMsg, %ecx
movl $errorMsgLen, %edx
int $0x80
jmp _salir
_lenString:
xor %ecx, %ecx
not %ecx
xor %al, %al
mov $0xA, %al
cld
repne scasb #Segmentation fault is caused by this line
not %ecx
dec %ecx
ret
_suma:
movl $4, %eax
movl $1, %ebx
movl $displaySuma, %ecx
movl $displayRestaLen, %edx
int $0x80
movl $4, %eax
movl $1, %ebx
mov %r10d, %ecx
mov %r15d, %edx
int $0x80
movl $4, %eax
movl $1, %ebx
movl $enterChar, %ecx
movl $1, %edx
int $0x80
ret
_resta:
movl $4, %eax
movl $1, %ebx
movl $displayResta, %ecx
movl $displayRestaLen, %edx
int $0x80
movl $4, %eax
movl $1, %ebx
mov %r11d, %ecx
mov %r14d, %edx
int $0x80
movl $4, %eax
movl $1, %ebx
movl $enterChar, %ecx
movl $1, %edx
int $0x80
ret
_clear:
xor %eax, %eax
xor %ebx, %ebx
xor %ecx, %ecx
xor %edx, %edx
xor %esi, %esi
xor %edi, %edi
xor %r8d, %r8d
xor %r9d, %r9d
xor %r10d, %r10d
xor %r11d, %r11d
xor %r14d, %r14d
xor %r15d, %r15d
ret
我正在使用这个 makefile 来创建 .o 和 .exe 文件(由我的教授提供):
#*************************************************
# Executable name : hola
# Version : 2.0
# Created date : February 12, 2019
# Authors :
# Eduardo A. Canessa M
# Description : simple makefile for GAS
# Important Notice: To be used for GAS only
#*************************************************
#change the name "ejemplo" for the name of your source file
name=addSubInteger
#program to use as the assembler (you could use NASM or YASM for this makefile)
ASM=as
#flags for the assember
#ASM_F= #*** place here flags if needed ***
#program to use as linker
LINKER=ld
#link executable
$(name): $(name).o
$(LINKER) -o $(name) $(name).o
#assemble source code
$(name).o: $(name).s
$(ASM) $(ASM_F) -o $(name).o $(name).s
程序读取第一个用户输入后出现段错误。
这是 the NASM code of my program (希望您不介意其中的西类牙注释,但它与 GAS 上编写的程序本质上是相同的程序)。
我知道我已经编写了一些更高级的意大利面条代码,但这是我得出的解决方案。
最佳答案
movl num1, %edi
call _lenString #ECX now has num1 length
lea (num1), %esi
call _stringToInt #EAX now has num1 in integer
第一条指令不加载 %edi
中的地址。您可以像接下来调用 _stringToInt 一样使用 lea
。或者,如果您关心更短的编码,请编写 mov $num1, %edi
。
lea (num1), %edi
call _lenString #ECX now has num1 length
第二个数字存在同样的问题:
movl num2, %edi SAME PROBLEM
xor %ecx, %ecx
call _lenString
_intToString 子例程有 2 个问题!
%esi
中的地址。.lcomm buffer, 10
保留的缓冲区。这将破坏 buffer2 中的第一个字节。由于转换 32 位整数可以产生(最多)10 个字符,因此您需要将缓冲区扩大到 11 个字节,以便可以安全地存储字节大小的终止符。
.lcomm buffer, 11
.lcomm buffer2, 11
然后使用这段代码:
_intToString:
mov $10, %ebx
add %ebx, %esi #Instead of 'ADD $10, %ESI' now that EBX==10
mov (terminator), %dl
mov %dl, (%esi)
.next_digit1:
xor %edx, %edx
div %ebx
add $0x30, %edx ##
dec %esi
mov %dl, (%esi)
test %eax, %eax
jnz .next_digit1
mov %esi, %eax
ret
原始 NASM 来源使用
STRING_TERMINATOR equ 10
equ
在运行时不消耗内存。您的 terminator: .byte 0
确实使用了运行时内存! equ
的一个好的翻译是
.set terminator,0
现在你可以写了
_intToString:
mov $10, %ebx
add %ebx, %esi #Instead of 'ADD $10, %ESI' now that EBX==10
movb $terminator, (%esi)
关于linux - 如何在 GAS 汇编中使用 "repne scasb"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57774233/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!